Пример #1
0
/*
ssize_t fi_tsenddata(struct fid_ep *ep, void *buf, size_t len,
		void *desc, uint64_t data, fi_addr_t dest_addr, void *context);
*/
void do_tsenddata(int len)
{
	int ret;
	ssize_t sz;
	int source_done = 0, dest_done = 0;
	struct fi_cq_tagged_entry s_cqe, d_cqe;

	rdm_tagged_sr_init_data(source, len, 0xab);
	rdm_tagged_sr_init_data(target, len, 0);

	sz = fi_tsenddata(ep[0], source, len, loc_mr, (uint64_t)source,
			 gni_addr[1], len, target);
	cr_assert_eq(sz, 0);

	sz = fi_trecv(ep[1], target, len, rem_mr, gni_addr[0], len, 0, source);
	cr_assert_eq(sz, 0);

	/* need to progress both CQs simultaneously for rendezvous */
	do {
		ret = fi_cq_read(msg_cq[0], &s_cqe, 1);
		if (ret == 1) {
			source_done = 1;
		}
		ret = fi_cq_read(msg_cq[1], &d_cqe, 1);
		if (ret == 1) {
			dest_done = 1;
		}
	} while (!(source_done && dest_done));

	dbg_printf("got context events!\n");

	cr_assert(rdm_tagged_sr_check_data(source, target, len), "Data mismatch");
}
Пример #2
0
void api_tagged_send_recv(int len)
{
	ssize_t sz;
	uint64_t caps = fi[0]->caps;

	rdm_api_init_data(source, len, 0xab);
	rdm_api_init_data(target, len, 0);

	sz = fi_tsend(ep[0], source, len, loc_mr, gni_addr[1], len, target);
	if (TAG_SEND_ALLOWED(caps)) {
		cr_assert(sz == 0, "fi_tsend failed caps:0x%lx err:%ld",
			  caps, sz);
	} else {
		cr_assert(sz < 0, "fi_tsend should fail caps:0x%lx err:%ld",
			  caps, sz);
	}

	sz = fi_trecv(ep[1], target, len, rem_mr, gni_addr[0], len, 0, source);
	if (TAG_RECV_ALLOWED(caps)) {
		cr_assert(sz == 0, "fi_trecv failed caps:0x%lx err:%ld",
			  caps, sz);
	} else {
		cr_assert(sz < 0, "fi_trecv should fail caps:0x%lx err:%ld",
			  caps, sz);
	}
}
Пример #3
0
static int recv_xfer(int size)
{
	struct fi_cq_tagged_entry comp;
	int ret;

	do {
		ret = fi_cq_read(rcq, &comp, 1);
		if (ret < 0 && ret != -FI_EAGAIN) {
			if (ret == -FI_EAVAIL) {
				cq_readerr(rcq, "rcq");
			} else {
				FT_PRINTERR("fi_cq_read", ret);
			}
			return ret;
		}
	} while (ret == -FI_EAGAIN);

	/* Posting recv for next send. Hence tag_data + 1 */
	ret = fi_trecv(ep, buf, buffer_size, fi_mr_desc(mr), remote_fi_addr,
			tag_data + 1, 0, &fi_ctx_trecv);
	if (ret)
		FT_PRINTERR("fi_trecv", ret);

	return ret;
}
Пример #4
0
void do_tinject(int len)
{
	int ret;
	ssize_t sz;
	struct fi_cq_tagged_entry cqe;

	rdm_tagged_sr_init_data(source, len, 0x23);
	rdm_tagged_sr_init_data(target, len, 0);

	sz = fi_tinject(ep[0], source, len, gni_addr[1], len);
	cr_assert_eq(sz, 0);

	sz = fi_trecv(ep[1], target, len, rem_mr, gni_addr[0], len, 0, source);
	cr_assert_eq(sz, 0);

	while ((ret = fi_cq_read(msg_cq[1], &cqe, 1)) == -FI_EAGAIN) {
		pthread_yield();
	}

	cr_assert_eq(ret, 1);
	cr_assert_eq((uint64_t)cqe.op_context, (uint64_t)source);

	dbg_printf("got recv context event!\n");

	cr_assert(rdm_tagged_sr_check_data(source, target, len), "Data mismatch");
}
Пример #5
0
Test(rdm_tagged_sr, multi_tsend_trecv) {
	int i, it, ridx, ret;
	const int iters = 37;
	const int num_msgs = 17;
	const int slen = 256;
	uint64_t tags[num_msgs];
	uint64_t rtag = 0x01000000;
	uint64_t ignore = 0xf0ffffff;
	char msg[num_msgs][slen];
	struct fi_cq_tagged_entry cqe;

	srand(time(NULL));

	for (it = 0; it < iters; it++) {
		for (i = 0; i < num_msgs; i++) {
			tags[i] = 0x01010abc + it*iters + i;

			sprintf(msg[i], "%d\n", i);
			ret = fi_tsend(ep[1], msg[i], strlen(msg[i]),
				       NULL, gni_addr[0], tags[i], NULL);
			cr_assert(ret == FI_SUCCESS);

			do {
				ret = fi_cq_read(msg_cq[1], &cqe, 1);
				cr_assert((ret == 1) || (ret == -FI_EAGAIN));
			} while (ret == -FI_EAGAIN);

			cr_assert(cqe.len == 0);
			cr_assert(cqe.tag == 0);
		}

		for (i = 0; i < num_msgs; i++) {
			ret = fi_trecv(ep[0], target, BUF_SZ,
				       fi_mr_desc(loc_mr),
				       gni_addr[1], rtag, ignore, NULL);
			cr_assert(ret == FI_SUCCESS);

			do {
				ret = fi_cq_read(msg_cq[0], &cqe, 1);
				cr_assert((ret == 1) || (ret == -FI_EAGAIN));
			} while (ret == -FI_EAGAIN);

			cr_assert(rtag != cqe.tag);

			ret = sscanf(target, "%d", &ridx);
			cr_assert(ret == 1);
			cr_assert(cqe.len == strlen(msg[ridx]));

			/* zero out the tag for error checking below */
			tags[ridx] = 0;
		}

		/* Make sure we got everything */
		for (i = 0; i < num_msgs; i++)
			cr_assert(tags[i] == 0);
	}

}
Пример #6
0
static int post_recv(uint64_t tag)
{
	int ret;

	// posting recv for next send
	ret = fi_trecv(ep, buf, buffer_size, fi_mr_desc(mr), remote_fi_addr,
			tag, 0, &fi_ctx_recv);
	if (ret)
		FT_PRINTERR("fi_trecv", ret);
	
	return ret;
}
Пример #7
0
static int receive_loop(size_t size)
{
	int ret;
	int q_opts = 0;
	struct fi_context recv_ctx[max_opts];

	while (q_opts < max_opts) {
		do {
			ft_tag = q_opts + 1;
			if (tagged)
				ret = fi_trecv(ep, rx_buf, size, NULL, remote_fi_addr,
					ft_tag, 0x0, (void *) &recv_ctx[q_opts]);
			else
				ret = fi_recv(ep, rx_buf, size, NULL, remote_fi_addr,
					(void *) &recv_ctx[q_opts]);

			if (ret == FI_SUCCESS) {
				rx_seq++;
				q_opts++;
			}
		} while (!ret && (q_opts != max_opts));

		if (ret < 0) {
			if (ret == -FI_EAGAIN) {
				if (delay > 0)
					sleep(delay);

				ret = ft_get_rx_comp(rx_seq);
				if (ret)
					return ret;
			} else {
				FT_PRINTERR("Recv OP", ret);
				return ret;
			}
		}
	}

	if (delay > 0)
		sleep(delay);

	ret = ft_get_rx_comp(rx_seq);
	if (ret)
		return ret;

	if (opts.verbose)
		printf("Success: Completed %d queued ops\n", q_opts);

	return 0;
}
Пример #8
0
static int recv_msg(uint64_t tag)
{
	int ret;

	// posting recv for next send
	ret = fi_trecv(ep, buf, buffer_size, fi_mr_desc(mr), remote_fi_addr,
			tag, 0, &fi_ctx_recv);
	if (ret)
		FT_PRINTERR("fi_trecv", ret);
	
	// wait for the completion event
	ret = wait_for_tagged_completion(rcq, 1);

	return ret;
}
Пример #9
0
static int recv_msg(void)
{
	int ret;

	ret = fi_trecv(ep, buf, buffer_size, fi_mr_desc(mr), remote_fi_addr,
		       tag_control, 0, &fi_ctx_trecv);
	if (ret) {
		FT_PRINTERR("fi_trecv", ret);
		return ret;
	}

	ret = wait_for_completion_tagged(rcq, 1);

	return ret;
}
Пример #10
0
/*
ssize_t fi_tsendmsg(struct fid_ep *ep, const struct fi_msg *msg,
		uint64_t flags);
*/
void do_tsendmsg(int len)
{
	int ret;
	ssize_t sz;
	int source_done = 0, dest_done = 0;
	struct fi_cq_tagged_entry s_cqe, d_cqe;
	struct fi_msg_tagged msg;
	struct iovec iov;

	iov.iov_base = source;
	iov.iov_len = len;

	msg.msg_iov = &iov;
	msg.desc = (void **)&loc_mr;
	msg.iov_count = 1;
	msg.addr = gni_addr[1];
	msg.context = target;
	msg.data = (uint64_t)target;
	msg.tag = len;
	msg.ignore = 0;

	rdm_tagged_sr_init_data(source, len, 0xef);
	rdm_tagged_sr_init_data(target, len, 0);

	sz = fi_tsendmsg(ep[0], &msg, 0);
	cr_assert_eq(sz, 0);

	sz = fi_trecv(ep[1], target, len, rem_mr, gni_addr[0], len, 0, source);
	cr_assert_eq(sz, 0);

	/* need to progress both CQs simultaneously for rendezvous */
	do {
		ret = fi_cq_read(msg_cq[0], &s_cqe, 1);
		if (ret == 1) {
			source_done = 1;
		}
		ret = fi_cq_read(msg_cq[1], &d_cqe, 1);
		if (ret == 1) {
			dest_done = 1;
		}
	} while (!(source_done && dest_done));

	dbg_printf("got context events!\n");

	cr_assert(rdm_tagged_sr_check_data(source, target, len), "Data mismatch");
}
Пример #11
0
/*
ssize_t fi_tsendv(struct fid_ep *ep, const struct iovec *iov,
		void **desc, size_t count, fi_addr_t dest_addr, uint64_t tag,
		void *context);
 */
void do_tsendv(int len)
{
	int i, ret, iov_cnt;
	ssize_t sz;
	int source_done = 0, dest_done = 0;
	struct fi_cq_tagged_entry s_cqe, d_cqe;

	sz = fi_tsendv(ep[0], src_iov, NULL, 0, gni_addr[1],
		       len * IOV_CNT, iov_dest_buf);
	cr_assert_eq(sz, -FI_EINVAL);

	for (iov_cnt = 1; iov_cnt <= IOV_CNT; iov_cnt++) {
		rdm_tagged_sr_init_data(iov_dest_buf, len * iov_cnt, 0);

		for (i = 0; i < iov_cnt; i++) {
			rdm_tagged_sr_init_data(src_iov[i].iov_base, len, 0xab);
			src_iov[i].iov_len = len;
		}

		sz = fi_tsendv(ep[0], src_iov, NULL, iov_cnt, gni_addr[1],
			       len * iov_cnt, iov_dest_buf);
		cr_assert_eq(sz, 0);

		sz = fi_trecv(ep[1], iov_dest_buf, len * iov_cnt, NULL, gni_addr[0],
			      len * iov_cnt, 0, src_iov);
		cr_assert_eq(sz, 0);

		/* need to progress both CQs simultaneously for rendezvous */
		do {
			ret = fi_cq_read(msg_cq[0], &s_cqe, 1);
			if (ret == 1) {
				source_done = 1;
			}
			ret = fi_cq_read(msg_cq[1], &d_cqe, 1);
			if (ret == 1) {
				dest_done = 1;
			}
		} while (!(source_done && dest_done));

		dbg_printf("got recv context event!\n");

		cr_assert(rdm_tagged_sr_check_iov_data(src_iov, iov_dest_buf, iov_cnt),
			  "Data mismatch");
		source_done = dest_done = 0;
	}
}
Пример #12
0
ssize_t ft_post_rx(size_t size)
{
	ssize_t ret;

	if (hints->caps & FI_TAGGED) {
		ret = fi_trecv(ep, rx_buf, size + ft_rx_prefix_size(), fi_mr_desc(mr),
				0, rx_seq, 0, &rx_ctx);
	} else {
		ret = fi_recv(ep, rx_buf, size + ft_rx_prefix_size(), fi_mr_desc(mr),
				0, &rx_ctx);
	}
	if (ret) {
		FT_PRINTERR("receive", ret);
		return ret;
	}

	rx_seq++;
	return 0;
}
Пример #13
0
static void do_tagged_sr_pipelined(void)
{
	int i, it, s, ret;
	const int iters = 37;
	const int num_msgs = 61;
	const int msgs_per_stage = 17;
	const int num_stages = num_msgs/msgs_per_stage +
		(num_msgs%msgs_per_stage != 0);
	const int slen = 256;
	uint64_t tags[num_msgs];
	uint64_t rtag = 0x01000000;
	uint64_t ignore = 0xf0ffffff;
	char msg[num_msgs][slen];
	struct fi_cq_tagged_entry cqe;

	srand(time(NULL));

	for (it = 0; it < iters; it++) {
		dbg_printf("iter %d\n", it);
		for (s = 0; s < num_stages; s++) {
			dbg_printf("\tsending stage %d\n", s);
			for (i = s*msgs_per_stage;
			     i < (s+1)*msgs_per_stage && i < num_msgs;
			     i++) {
				tags[i] = 0x01010abc + it*iters + i;

				sprintf(msg[i], "%d\n", i%10);
				ret = fi_tsend(ep[1], msg[i], strlen(msg[i]),
					       NULL, gni_addr[0], tags[i],
					       NULL);
				cr_assert(ret == FI_SUCCESS);
			}

			for (i = s*msgs_per_stage;
			     i < (s+1)*msgs_per_stage && i < num_msgs;
			     i++) {
				do {
					ret = fi_cq_read(msg_cq[1], &cqe, 1);
					cr_assert((ret == 1) ||
						  (ret == -FI_EAGAIN));
				} while (ret == -FI_EAGAIN);

				cr_assert(cqe.tag == 0);
			}
			cr_assert(cqe.len == 0);
		}

		for (s = 0; s < num_stages; s++) {
			dbg_printf("\treceiving stage %d\n", s);
			for (i = s*msgs_per_stage;
			     i < (s+1)*msgs_per_stage && i < num_msgs;
			     i++) {
				ret = fi_trecv(ep[0], &target[i], BUF_SZ,
					       fi_mr_desc(loc_mr),
					       gni_addr[1], rtag, ignore,
					       NULL);
				cr_assert(ret == FI_SUCCESS);
			}

			for (i = s*msgs_per_stage;
			     i < (s+1)*msgs_per_stage && i < num_msgs;
			     i++) {
				do {
					ret = fi_cq_read(msg_cq[0], &cqe, 1);
					cr_assert((ret == 1) ||
						  (ret == -FI_EAGAIN));
				} while (ret == -FI_EAGAIN);

				cr_assert(rtag != cqe.tag);

				cr_assert(ret == 1);
				cr_assert(cqe.len == 2);

				/* zero out the tag for error checking below */
				tags[cqe.tag - (0x01010abc + it*iters)] = 0;
			}
		}

		/* Make sure we got everything */
		for (i = 0; i < num_msgs; i++) {
			cr_assert(tags[i] == 0);
		}
	}

}
Пример #14
0
static int init_av(void)
{
	int ret;

	if (opts.dst_addr) {
		/* Get local address blob. Find the addrlen first. We set addrlen 
		 * as 0 and fi_getname will return the actual addrlen. */
		addrlen = 0;
		ret = fi_getname(&ep->fid, local_addr, &addrlen);
		if (ret != -FI_ETOOSMALL) {
			FT_PRINTERR("fi_getname", ret);
			return ret;
		}

		local_addr = malloc(addrlen);
		ret = fi_getname(&ep->fid, local_addr, &addrlen);
		if (ret) {
			FT_PRINTERR("fi_getname", ret);
			return ret;
		}

		ret = fi_av_insert(av, remote_addr, 1, &remote_fi_addr, 0, 
				&fi_ctx_av);
		if (ret != 1) {
			FT_PRINTERR("fi_av_insert", ret);
			return ret;
		}

		/* Send local addr size and local addr */
		memcpy(buf, &addrlen, sizeof(size_t));
		memcpy(buf + sizeof(size_t), local_addr, addrlen);
		ret = send_msg(sizeof(size_t) + addrlen);
		if (ret)
			return ret;

		/* Receive ACK from server */
		ret = recv_msg();
		if (ret)
			return ret;

	} else {
		/* Post a recv to get the remote address */
		ret = recv_msg();
		if (ret)
			return ret;

		memcpy(&addrlen, buf, sizeof(size_t));
		remote_addr = malloc(addrlen);
		memcpy(remote_addr, buf + sizeof(size_t), addrlen);

		ret = fi_av_insert(av, remote_addr, 1, &remote_fi_addr, 0, 
				&fi_ctx_av);
		if (ret != 1) {
			FT_PRINTERR("fi_av_insert", ret);
			return ret;
		}

		/* Send ACK */
		ret = send_msg(16);
		if (ret)
			return ret;
	}

	/* Post first recv */
	ret = fi_trecv(ep, buf, buffer_size, fi_mr_desc(mr), remote_fi_addr,
			tag_data, 0, &fi_ctx_trecv);
	if (ret)
		FT_PRINTERR("fi_trecv", ret);

	return ret;
}
Пример #15
0
static int run(void)
{
	int ret;

	ret = init_fabric();
	if (ret)
		return ret;

	ret = ft_init_av();
	if (ret)
		return ret;

	if (opts.dst_addr) {
		printf("Searching for a bad msg\n");
		ret = tagged_peek(0xbad);
		if (ret != -FI_ENOMSG) {
			FT_PRINTERR("FI_PEEK", ret);
			return ret;
		}

		printf("Synchronizing with sender..\n");
		ret = ft_sync();
		if (ret)
			return ret;

		printf("Searching for a good msg\n");
		ret = tagged_peek(0x900d);
		if (ret != 1) {
			FT_PRINTERR("FI_PEEK", ret);
			return ret;
		}

		printf("Receiving msg\n");
		ret = fi_trecv(ep, buf, rx_size, fi_mr_desc(mr), remote_fi_addr,
				0x900d, 0, &rx_ctx);
		if (ret) {
			FT_PRINTERR("fi_trecv", ret);
			return ret;
		}

		printf("Completing recv\n");
		ret = ft_get_rx_comp(++rx_seq);
		if (ret)
			return ret;

	} else {
		printf("Sending tagged message\n");
		ret = fi_tsend(ep, tx_buf, tx_size, fi_mr_desc(mr),
				remote_fi_addr, 0x900d, &tx_ctx);
		if (ret)
			return ret;

		printf("Synchronizing with receiver..\n");
		ret = ft_sync();
		if (ret)
			return ret;

		printf("Getting send completion\n");
		ret = ft_get_tx_comp(tx_seq + 1);
		if (ret)
			return ret;
	}

	ft_finalize();
	return 0;
}