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; }
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; }
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; }
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"); } }
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"); }