예제 #1
0
int mca_btl_ofi_acswap (struct mca_btl_base_module_t *btl, struct mca_btl_base_endpoint_t *endpoint,
                        void *local_address, uint64_t remote_address, mca_btl_base_registration_handle_t *local_handle,
                        mca_btl_base_registration_handle_t *remote_handle, uint64_t compare, uint64_t value, int flags,
                        int order, mca_btl_base_rdma_completion_fn_t cbfunc, void *cbcontext, void *cbdata)
{
    int rc;
    int fi_datatype = FI_UINT64;

    mca_btl_ofi_module_t *ofi_btl = (mca_btl_ofi_module_t *) btl;
    mca_btl_ofi_endpoint_t *btl_endpoint = (mca_btl_ofi_endpoint_t*) endpoint;
    mca_btl_ofi_completion_t *comp = NULL;
    mca_btl_ofi_context_t *ofi_context;

    ofi_context = get_ofi_context(ofi_btl);

    if (flags & MCA_BTL_ATOMIC_FLAG_32BIT) {
        fi_datatype = FI_UINT32;
    }

    comp = mca_btl_ofi_completion_alloc(btl, endpoint,
                                        ofi_context,
                                        local_address,
                                        local_handle,
                                        cbfunc, cbcontext, cbdata,
                                        MCA_BTL_OFI_TYPE_CSWAP);

    /* copy the operand because it might get freed from upper layer */
    comp->operand = (uint64_t) value;
    comp->compare = (uint64_t) compare;

    remote_address = (remote_address - (uint64_t) remote_handle->base_addr);

    /* perform atomic */
    rc = fi_compare_atomic(ofi_context->tx_ctx,
                           (void*) &comp->operand, 1, NULL,
                           (void*) &comp->compare, NULL,
                           local_address, local_handle->desc,
                           btl_endpoint->peer_addr,
                           remote_address, remote_handle->rkey,
                           fi_datatype,
                           FI_CSWAP,
                           comp);

    if (rc == -FI_EAGAIN) {
        return OPAL_ERR_OUT_OF_RESOURCE;
    } else if (rc < 0) {
        BTL_ERROR(("fi_compare_atomic failed with rc=%d (%s)", rc, fi_strerror(-rc)));
        MCA_BTL_OFI_ABORT();
    }

    MCA_BTL_OFI_NUM_RDMA_INC(ofi_btl);

    return OPAL_SUCCESS;
}
예제 #2
0
static int execute_compare_atomic_op(enum fi_op op)
{
	int ret;
	
	ret = fi_compare_atomic(ep, buf, 1, fi_mr_desc(mr), compare, 
			fi_mr_desc(mr_compare), result, fi_mr_desc(mr_result), 
			remote_fi_addr, remote.addr, remote.key, datatype, op, 
			&fi_ctx_atomic);
	if (ret) {
		FT_PRINTERR("fi_compare_atomic", ret);
	} else {			
		ret = wait_for_completion(scq, 1);
	}
	
	return ret;
}
예제 #3
0
static int execute_compare_atomic_op(enum fi_op op)
{
	int ret;
	
	ret = fi_compare_atomic(ep, buf, 1, fi_mr_desc(mr), compare, 
			fi_mr_desc(mr_compare), result, fi_mr_desc(mr_result), 
			remote_fi_addr, remote.addr, remote.key, datatype, op, 
			&fi_ctx_atomic);
	if (ret) {
		fprintf(stderr, "fi_compare_atomic %d (%s)\n", ret, 
				fi_strerror(-ret));
	} else {			
		ret = wait_for_completion(scq, 1);
	}
	
	return ret;
}
예제 #4
0
void sep_invalid_compare_atomic(enum fi_datatype dt, enum fi_op op)
{
	ssize_t sz;
	size_t count;
	uint64_t operand, op2;

	if (!supported_compare_atomic_ops[op][dt]) {
		sz = fi_compare_atomic(tx_ep[0][0], &operand, 1, NULL,
				       &op2, NULL, source, loc_mr,
				       rx_addr[0], (uint64_t)target, mr_key[1],
				       dt, op, target);
		cr_assert(sz == -FI_ENOENT);

		sz = fi_compare_atomicvalid(tx_ep[0][0], dt, op, &count);
		cr_assert(sz == -FI_ENOENT, "fi_atomicvalid() succeeded\n");
	} else {
		sz = fi_compare_atomicvalid(tx_ep[0][0], dt, op, &count);
		cr_assert(!sz, "fi_atomicvalid() failed\n");
		cr_assert(count == 1, "fi_atomicvalid(): bad count\n");
	}
}
예제 #5
0
void sep_atomic_compwrite(int index)
{
	int ret;
	ssize_t sz;
	struct fi_cq_tagged_entry cqe = { (void *) -1, UINT_MAX, UINT_MAX,
					  (void *) -1, UINT_MAX, UINT_MAX };
	uint64_t operand = SOURCE_DATA, op2 = TARGET_DATA;
	uint64_t w[NUMEPS] = {0}, r[NUMEPS] = {0}, w_e[NUMEPS] = {0};
	uint64_t r_e[NUMEPS] = {0};

	/* u64 */
	*((uint64_t *)source) = FETCH_SOURCE_DATA;
	*((uint64_t *)target) = TARGET_DATA;
	sz = fi_compare_atomic(tx_ep[0][index], &operand, 1, NULL, &op2, NULL,
			       source, loc_mr[0], rx_addr[index],
			       (uint64_t)target, mr_key[1], FI_UINT64,
			       FI_CSWAP, target);
	cr_assert_eq(sz, 0, "fi_compare_atomic returned %ld (%s)", sz,
		     fi_strerror(-sz));

	/* reset cqe */
	cqe.op_context = cqe.buf = (void *) -1;
	cqe.flags = cqe.len = cqe.data = cqe.tag = UINT_MAX;
	while ((ret = fi_cq_read(tx_cq[0][index], &cqe, 1)) == -FI_EAGAIN) {
		pthread_yield();
	}

	cr_assert_eq(ret, 1);
	sep_check_tcqe(&cqe, target, FI_ATOMIC | FI_READ, 0);

	r[0] = 1;
	sep_check_cntrs(w, r, w_e, r_e);
	ret = *((uint64_t *)target) == SOURCE_DATA;
	cr_assert(ret, "Data mismatch");
	ret = *((uint64_t *)source) == TARGET_DATA;
	cr_assert(ret, "Fetch data mismatch");
}