static ucs_status_t ucp_address_do_pack(ucp_worker_h worker, ucp_ep_h ep, void *buffer, size_t size, uint64_t tl_bitmap, unsigned *order, const ucp_address_packed_device_t *devices, ucp_rsc_index_t num_devices) { ucp_context_h context = worker->context; const ucp_address_packed_device_t *dev; uct_iface_attr_t *iface_attr; ucp_rsc_index_t md_index; ucs_status_t status; ucp_rsc_index_t i; size_t iface_addr_len; size_t ep_addr_len; uint64_t md_flags; unsigned index; void *ptr; uint8_t *iface_addr_len_ptr; ptr = buffer; index = 0; *(uint64_t*)ptr = worker->uuid; ptr += sizeof(uint64_t); ptr = ucp_address_pack_string(ucp_worker_get_name(worker), ptr); if (num_devices == 0) { *((uint8_t*)ptr) = UCP_NULL_RESOURCE; ++ptr; goto out; } for (dev = devices; dev < devices + num_devices; ++dev) { /* MD index */ md_index = context->tl_rscs[dev->rsc_index].md_index; md_flags = context->tl_mds[md_index].attr.cap.flags; ucs_assert_always(!(md_index & ~UCP_ADDRESS_FLAG_MD_MASK)); *(uint8_t*)ptr = md_index | ((dev->tl_bitmap == 0) ? UCP_ADDRESS_FLAG_EMPTY : 0) | ((md_flags & UCT_MD_FLAG_ALLOC) ? UCP_ADDRESS_FLAG_MD_ALLOC : 0) | ((md_flags & UCT_MD_FLAG_REG) ? UCP_ADDRESS_FLAG_MD_REG : 0); ++ptr; /* Device address length */ ucs_assert(dev->dev_addr_len < UCP_ADDRESS_FLAG_LAST); *(uint8_t*)ptr = dev->dev_addr_len | ((dev == (devices + num_devices - 1)) ? UCP_ADDRESS_FLAG_LAST : 0); ++ptr; /* Device address */ status = uct_iface_get_device_address(worker->ifaces[dev->rsc_index].iface, (uct_device_addr_t*)ptr); if (status != UCS_OK) { return status; } ucp_address_memchek(ptr, dev->dev_addr_len, &context->tl_rscs[dev->rsc_index].tl_rsc); ptr += dev->dev_addr_len; for (i = 0; i < context->num_tls; ++i) { if (!(UCS_BIT(i) & dev->tl_bitmap)) { continue; } /* Transport name checksum */ *(uint16_t*)ptr = context->tl_rscs[i].tl_name_csum; ptr += sizeof(uint16_t); /* Transport information */ ucp_address_pack_iface_attr(ptr, &worker->ifaces[i].attr, worker->atomic_tls & UCS_BIT(i)); ucp_address_memchek(ptr, sizeof(ucp_address_packed_iface_attr_t), &context->tl_rscs[dev->rsc_index].tl_rsc); ptr += sizeof(ucp_address_packed_iface_attr_t); iface_attr = &worker->ifaces[i].attr; if (!(iface_attr->cap.flags & UCT_IFACE_FLAG_CONNECT_TO_IFACE) && !(iface_attr->cap.flags & UCT_IFACE_FLAG_CONNECT_TO_EP)) { return UCS_ERR_INVALID_ADDR; } /* Pack iface address */ iface_addr_len = iface_attr->iface_addr_len; ucs_assert(iface_addr_len < UCP_ADDRESS_FLAG_EP_ADDR); status = uct_iface_get_address(worker->ifaces[i].iface, (uct_iface_addr_t*)(ptr + 1)); if (status != UCS_OK) { return status; } ucp_address_memchek(ptr + 1, iface_addr_len, &context->tl_rscs[dev->rsc_index].tl_rsc); iface_addr_len_ptr = ptr; *iface_addr_len_ptr = iface_addr_len | ((i == ucs_ilog2(dev->tl_bitmap)) ? UCP_ADDRESS_FLAG_LAST : 0); ptr += 1 + iface_addr_len; /* Pack ep address if present */ if (!(iface_attr->cap.flags & UCT_IFACE_FLAG_CONNECT_TO_IFACE) && (ep != NULL)) { *iface_addr_len_ptr |= UCP_ADDRESS_FLAG_EP_ADDR; ep_addr_len = iface_attr->ep_addr_len; ucs_assert(ep_addr_len < UINT8_MAX); *(uint8_t*)ptr = ep_addr_len; status = ucp_address_pack_ep_address(ep, i, ptr + 1); if (status != UCS_OK) { return status; } ucp_address_memchek(ptr + 1, ep_addr_len, &context->tl_rscs[dev->rsc_index].tl_rsc); ptr += 1 + ep_addr_len; } /* Save the address index of this transport */ if (order != NULL) { order[ucs_count_one_bits(tl_bitmap & UCS_MASK(i))] = index; } ucs_trace("pack addr[%d] : "UCT_TL_RESOURCE_DESC_FMT " md_flags 0x%"PRIx64" tl_flags 0x%"PRIx64" bw %e ovh %e " "lat_ovh: %e dev_priority %d", index, UCT_TL_RESOURCE_DESC_ARG(&context->tl_rscs[i].tl_rsc), md_flags, worker->ifaces[i].attr.cap.flags, worker->ifaces[i].attr.bandwidth, worker->ifaces[i].attr.overhead, worker->ifaces[i].attr.latency.overhead, worker->ifaces[i].attr.priority); ++index; } } out: ucs_assertv(buffer + size == ptr, "buffer=%p size=%zu ptr=%p ptr-buffer=%zd", buffer, size, ptr, ptr - buffer); return UCS_OK; }
static ucs_status_t ucp_address_do_pack(ucp_worker_h worker, ucp_ep_h ep, void *buffer, size_t size, uint64_t tl_bitmap, unsigned *order, const ucp_address_packed_device_t *devices, ucp_rsc_index_t num_devices) { ucp_context_h context = worker->context; const ucp_address_packed_device_t *dev; uct_iface_attr_t *iface_attr; ucs_status_t status; ucp_rsc_index_t i; size_t tl_addr_len; unsigned index; void *ptr; ptr = buffer; index = 0; *(uint64_t*)ptr = worker->uuid; ptr += sizeof(uint64_t); ptr = ucp_address_pack_string(ucp_worker_get_name(worker), ptr); if (num_devices == 0) { *((uint8_t*)ptr) = UCP_NULL_RESOURCE; ++ptr; goto out; } for (dev = devices; dev < devices + num_devices; ++dev) { /* PD index */ *(uint8_t*)ptr = context->tl_rscs[dev->rsc_index].pd_index | ((dev->tl_bitmap == 0) ? UCP_ADDRESS_FLAG_EMPTY : 0); ++ptr; /* Device address length */ ucs_assert(dev->dev_addr_len < UCP_ADDRESS_FLAG_LAST); *(uint8_t*)ptr = dev->dev_addr_len | ((dev == (devices + num_devices - 1)) ? UCP_ADDRESS_FLAG_LAST : 0); ++ptr; /* Device address */ status = uct_iface_get_device_address(worker->ifaces[dev->rsc_index], (uct_device_addr_t*)ptr); if (status != UCS_OK) { return status; } ptr += dev->dev_addr_len; for (i = 0; i < context->num_tls; ++i) { if (!(UCS_BIT(i) & dev->tl_bitmap)) { continue; } /* Transport name */ ptr = ucp_address_pack_string(context->tl_rscs[i].tl_rsc.tl_name, ptr); /* Transport address length */ iface_attr = &worker->iface_attrs[i]; if (iface_attr->cap.flags & UCT_IFACE_FLAG_CONNECT_TO_IFACE) { tl_addr_len = iface_attr->iface_addr_len; status = uct_iface_get_address(worker->ifaces[i], (uct_iface_addr_t*)(ptr + 1)); } else if (iface_attr->cap.flags & UCT_IFACE_FLAG_CONNECT_TO_EP) { if (ep == NULL) { tl_addr_len = 0; status = UCS_OK; } else { tl_addr_len = iface_attr->ep_addr_len; status = ucp_address_pack_ep_address(ep, i, ptr + 1); } } else { status = UCS_ERR_INVALID_ADDR; } if (status != UCS_OK) { return status; } ucp_address_memchek(ptr + 1, tl_addr_len, &context->tl_rscs[dev->rsc_index].tl_rsc); /* Save the address index of this transport */ if (order != NULL) { order[ucs_count_one_bits(tl_bitmap & UCS_MASK(i))] = index++; } ucs_assert(tl_addr_len < UCP_ADDRESS_FLAG_LAST); *(uint8_t*)ptr = tl_addr_len | ((i == ucs_ilog2(dev->tl_bitmap)) ? UCP_ADDRESS_FLAG_LAST : 0); ptr += 1 + tl_addr_len; } } out: ucs_assertv(buffer + size == ptr, "buffer=%p size=%zu ptr=%p", buffer, size, ptr); return UCS_OK; }