static ucs_status_t ucp_tag_eager_contig_short(uct_pending_req_t *self) { ucp_request_t *req = ucs_container_of(self, ucp_request_t, send.uct); ucp_ep_t *ep = req->send.ep; ucs_status_t status; req->send.lane = ucp_ep_get_am_lane(ep); status = uct_ep_am_short(ep->uct_eps[req->send.lane], UCP_AM_ID_EAGER_ONLY, req->send.tag.tag, req->send.buffer, req->send.length); if (status != UCS_OK) { return status; } ucp_request_complete_send(req, UCS_OK); return UCS_OK; }
ucs_status_t ucp_tag_send(ucp_ep_h ep, const void *buffer, size_t length, ucp_tag_t tag) { ucp_worker_h worker = ep->worker; ucs_status_t status; retry: if (ucs_likely(length < ep->config.max_short_tag)) { UCS_STATIC_ASSERT(sizeof(ucp_tag_t) == sizeof(uint64_t)); status = uct_ep_am_short(ep->uct_ep, UCP_AM_ID_EAGER_ONLY, tag, buffer, length); if (status == UCS_ERR_NO_RESOURCE) { ucp_worker_progress(worker); goto retry; } return status; } ucs_fatal("unsupported"); }
int main(int argc, char **argv) { /* MPI is initially used to swap the endpoint and interface addresses so each * process has knowledge of the others. */ int partner; int size, rank; uct_device_addr_t *own_dev, *peer_dev; uct_iface_addr_t *own_iface, *peer_iface; uct_ep_addr_t *own_ep, *peer_ep; ucs_status_t status; /* status codes for UCS */ uct_ep_h ep; /* Remote endpoint */ ucs_async_context_t async; /* Async event context manages times and fd notifications */ uint8_t id = 0; void *arg; const char *tl_name = NULL; const char *dev_name = NULL; struct iface_info if_info; int exit_fail = 1; optind = 1; if (3 == argc) { dev_name = argv[1]; tl_name = argv[2]; } else { printf("Usage: %s (<dev-name> <tl-name>)\n", argv[0]); fflush(stdout); return 1; } MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &size); if (size < 2) { fprintf(stderr, "Failed to create enough mpi processes\n"); goto out; } MPI_Comm_rank(MPI_COMM_WORLD, &rank); if (0 == rank) { partner = 1; } else if (1 == rank) { partner = 0; } else { /* just wait for other processes in MPI_Finalize */ exit_fail = 0; goto out; } /* Initialize context */ status = ucs_async_context_init(&async, UCS_ASYNC_MODE_THREAD); CHKERR_JUMP(UCS_OK != status, "init async context", out); /* Create a worker object */ status = uct_worker_create(&async, UCS_THREAD_MODE_SINGLE, &if_info.worker); CHKERR_JUMP(UCS_OK != status, "create worker", out_cleanup_async); /* Search for the desired transport */ status = dev_tl_lookup(dev_name, tl_name, &if_info); CHKERR_JUMP(UCS_OK != status, "find supported device and transport", out_destroy_worker); /* Expect that addr len is the same on both peers */ own_dev = (uct_device_addr_t*)calloc(2, if_info.attr.device_addr_len); CHKERR_JUMP(NULL == own_dev, "allocate memory for dev addrs", out_destroy_iface); peer_dev = (uct_device_addr_t*)((char*)own_dev + if_info.attr.device_addr_len); own_iface = (uct_iface_addr_t*)calloc(2, if_info.attr.iface_addr_len); CHKERR_JUMP(NULL == own_iface, "allocate memory for if addrs", out_free_dev_addrs); peer_iface = (uct_iface_addr_t*)((char*)own_iface + if_info.attr.iface_addr_len); /* Get device address */ status = uct_iface_get_device_address(if_info.iface, own_dev); CHKERR_JUMP(UCS_OK != status, "get device address", out_free_if_addrs); MPI_Sendrecv(own_dev, if_info.attr.device_addr_len, MPI_BYTE, partner, 0, peer_dev, if_info.attr.device_addr_len, MPI_BYTE, partner,0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); status = uct_iface_is_reachable(if_info.iface, peer_dev, NULL); CHKERR_JUMP(0 == status, "reach the peer", out_free_if_addrs); /* Get interface address */ if (if_info.attr.cap.flags & UCT_IFACE_FLAG_CONNECT_TO_IFACE) { status = uct_iface_get_address(if_info.iface, own_iface); CHKERR_JUMP(UCS_OK != status, "get interface address", out_free_if_addrs); MPI_Sendrecv(own_iface, if_info.attr.iface_addr_len, MPI_BYTE, partner, 0, peer_iface, if_info.attr.iface_addr_len, MPI_BYTE, partner,0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); } /* Again, expect that ep addr len is the same on both peers */ own_ep = (uct_ep_addr_t*)calloc(2, if_info.attr.ep_addr_len); CHKERR_JUMP(NULL == own_ep, "allocate memory for ep addrs", out_free_if_addrs); peer_ep = (uct_ep_addr_t*)((char*)own_ep + if_info.attr.ep_addr_len); if (if_info.attr.cap.flags & UCT_IFACE_FLAG_CONNECT_TO_EP) { /* Create new endpoint */ status = uct_ep_create(if_info.iface, &ep); CHKERR_JUMP(UCS_OK != status, "create endpoint", out_free_ep_addrs); /* Get endpoint address */ status = uct_ep_get_address(ep, own_ep); CHKERR_JUMP(UCS_OK != status, "get endpoint address", out_free_ep); } MPI_Sendrecv(own_ep, if_info.attr.ep_addr_len, MPI_BYTE, partner, 0, peer_ep, if_info.attr.ep_addr_len, MPI_BYTE, partner, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); if (if_info.attr.cap.flags & UCT_IFACE_FLAG_CONNECT_TO_EP) { /* Connect endpoint to a remote endpoint */ status = uct_ep_connect_to_ep(ep, peer_dev, peer_ep); MPI_Barrier(MPI_COMM_WORLD); } else if (if_info.attr.cap.flags & UCT_IFACE_FLAG_CONNECT_TO_IFACE) { /* Create an endpoint which is connected to a remote interface */ status = uct_ep_create_connected(if_info.iface, peer_dev, peer_iface, &ep); } else { status = UCS_ERR_UNSUPPORTED; } CHKERR_JUMP(UCS_OK != status, "connect endpoint", out_free_ep); /*Set active message handler */ status = uct_iface_set_am_handler(if_info.iface, id, hello_world, arg, UCT_AM_CB_FLAG_SYNC); CHKERR_JUMP(UCS_OK != status, "set callback", out_free_ep); if (0 == rank) { uint64_t header; char payload[8]; unsigned length = sizeof(payload); /* Send active message to remote endpoint */ status = uct_ep_am_short(ep, id, header, payload, length); CHKERR_JUMP(UCS_OK != status, "send active msg", out_free_ep); } else if (1 == rank) { while (holder) { /* Explicitly progress any outstanding active message requests */ uct_worker_progress(if_info.worker); } } /* Everything is fine, we need to call MPI_Finalize rather than MPI_Abort */ exit_fail = 0; out_free_ep: uct_ep_destroy(ep); out_free_ep_addrs: free(own_ep); out_free_if_addrs: free(own_iface); out_free_dev_addrs: free(own_dev); out_destroy_iface: uct_iface_close(if_info.iface); uct_md_close(if_info.pd); out_destroy_worker: uct_worker_destroy(if_info.worker); out_cleanup_async: ucs_async_context_cleanup(&async); out: (0 == exit_fail) ? MPI_Finalize() : MPI_Abort(MPI_COMM_WORLD, 1); return exit_fail; }
int main(int argc, char **argv) { /* MPI is initially used to swap the endpoint and interface addresses so each * process has knowledge of the others. */ MPI_Status mpi_status; int partner; int size; struct sockaddr *ep_addr; /* Endpoint address */ struct sockaddr *iface_addr; /* Interface address */ ucs_status_t status; /* status codes for UCS */ ucs_thread_mode_t thread_mode = UCS_THREAD_MODE_SINGLE; /* Specifies thread sharing mode of an object */ uct_ep_h ep; /* Remote endpoint */ void *arg; MPI_Init(NULL, NULL); MPI_Comm_size(MPI_COMM_WORLD, &size); if (size < 2) { fprintf(stderr, "Failed to create enough mpi processes.\n");fflush(stderr); return 1; } MPI_Comm_rank(MPI_COMM_WORLD, &rank); if (0 == rank) { partner = 1; } else if (1 == rank) { partner = 0; } else { MPI_Finalize(); return 0; } /* Initialize context */ status = ucs_async_context_init(&async, UCS_ASYNC_MODE_THREAD); if (UCS_OK != status) { fprintf(stderr, "Failed to init async context.\n");fflush(stderr); goto out; } /* Create a worker object */ status = uct_worker_create(&async, thread_mode, &worker); if (UCS_OK != status) { fprintf(stderr, "Failed to create worker.\n");fflush(stderr); goto out_cleanup_async; } /* The device and tranport names are determined by latency */ status = dev_tl_lookup(); if (UCS_OK != status) { fprintf(stderr, "Failed to find supported device and transport\n");fflush(stderr); goto out_destroy_worker; } iface_addr = calloc(1, iface_attr.iface_addr_len); ep_addr = calloc(1, iface_attr.ep_addr_len); if ((NULL == iface_addr) || (NULL == ep_addr)) { goto out_destroy_iface; } /* Get interface address */ status = uct_iface_get_address(iface, iface_addr); if (UCS_OK != status) { fprintf(stderr, "Failed to get interface address.\n");fflush(stderr); goto out_free; } if (iface_attr.cap.flags & UCT_IFACE_FLAG_CONNECT_TO_EP) { /* Create new endpoint */ status = uct_ep_create(iface, &ep); if (UCS_OK != status) { fprintf(stderr, "Failed to create endpoint.\n");fflush(stderr); goto out_free; } /* Get endpoint address */ status = uct_ep_get_address(ep, ep_addr); if (UCS_OK != status) { fprintf(stderr, "Failed to get endpoint address.\n");fflush(stderr); goto out_free_ep; } } /* Communicate interface and endpoint addresses to corresponding process */ MPI_Send(iface_addr, iface_attr.iface_addr_len, MPI_BYTE, partner, 0, MPI_COMM_WORLD); MPI_Recv(iface_addr, iface_attr.iface_addr_len, MPI_BYTE, partner, 0, MPI_COMM_WORLD, &mpi_status); MPI_Send(ep_addr, iface_attr.ep_addr_len, MPI_BYTE, partner, 0, MPI_COMM_WORLD); MPI_Recv(ep_addr, iface_attr.ep_addr_len, MPI_BYTE, partner, 0, MPI_COMM_WORLD, &mpi_status); if (iface_attr.cap.flags & UCT_IFACE_FLAG_CONNECT_TO_EP) { /* Connect endpoint to a remote endpoint */ status = uct_ep_connect_to_ep(ep, ep_addr); } else if (iface_attr.cap.flags & UCT_IFACE_FLAG_CONNECT_TO_IFACE) { /* Create an endpoint which is connected to a remote interface */ status = uct_ep_create_connected(iface, iface_addr, &ep); } else status = UCS_ERR_UNSUPPORTED; if (UCS_OK != status) { fprintf(stderr, "Failed to connect endpoint\n");fflush(stderr); goto out_free_ep; } uint8_t id = 0; /* Tag for active message */ /*Set active message handler */ status = uct_iface_set_am_handler(iface, id, hello_world, arg); if (UCS_OK != status) { fprintf(stderr, "Failed to set callback.\n");fflush(stderr); goto out_free_ep; } if (0 == rank) { uint64_t header; char payload[8]; unsigned length = sizeof(payload); /* Send active message to remote endpoint */ status = uct_ep_am_short(ep, id, header, payload, length); } else if (1 == rank) { while (holder) { /* Explicitly progress any outstanding active message requests */ uct_worker_progress(worker); } } out_free_ep: uct_ep_destroy(ep); out_free: free(iface_addr); free(ep_addr); out_destroy_iface: uct_iface_close(iface); uct_pd_close(pd); out_destroy_worker: uct_worker_destroy(worker); out_cleanup_async: ucs_async_context_cleanup(&async); out: MPI_Finalize(); return 0; }