int main(int argc, char* argv[]) { size_t packed_ddt_len; const void *packed_ddt; void *payload, *ptr; struct ompi_datatype_t *unpacked_dt; int ret = 0; int blen[2]; MPI_Aint disp[2]; MPI_Datatype newType, types[2], struct_type; MPI_Init(&argc, &argv); /* Basic test... */ printf("---> Basic test with MPI_INT\n"); packed_ddt_len = ompi_ddt_pack_description_length(MPI_INT); ptr = payload = malloc(packed_ddt_len); ret = ompi_ddt_get_pack_description(MPI_INT, &packed_ddt); if (ret != 0) goto cleanup; memcpy(payload, packed_ddt, packed_ddt_len); unpacked_dt = ompi_ddt_create_from_packed_description(&payload, ompi_proc_local()); free(ptr); if (unpacked_dt == MPI_INT) { printf("\tPASSED\n"); } else { printf("\tFAILED: datatypes don't match\n"); ret = 1; goto cleanup; } printf("---> Advanced test with hindexed\n"); blen[0] = 10; blen[1] = 10; disp[0] = 0; disp[1] = 20*sizeof(double); ret = MPI_Type_create_hindexed(2, blen, disp, MPI_DOUBLE, &newType); if (ret != 0) goto cleanup; ret = MPI_Type_commit(&newType); if (ret != 0) goto cleanup; packed_ddt_len = ompi_ddt_pack_description_length(newType); ptr = payload = malloc(packed_ddt_len); ret = ompi_ddt_get_pack_description(newType, &packed_ddt); if (ret != 0) goto cleanup; memcpy(payload, packed_ddt, packed_ddt_len); unpacked_dt = ompi_ddt_create_from_packed_description(&payload, ompi_proc_local()); free(ptr); if (unpacked_dt != NULL) { printf("\tPASSED\n"); } else { printf("\tFAILED: datatypes don't match\n"); ret = 1; goto cleanup; } printf("---> Even more advanced test using the previous type and struct\n"); blen[0] = 11; blen[1] = 2; disp[0] = 0; disp[1] = 64; types[0] = MPI_INT; types[1] = newType; MPI_Type_create_struct( 2, blen, disp, types, &struct_type ); if (ret != 0) goto cleanup; ret = MPI_Type_commit(&struct_type); if (ret != 0) goto cleanup; packed_ddt_len = ompi_ddt_pack_description_length(struct_type); ptr = payload = malloc(packed_ddt_len); ret = ompi_ddt_get_pack_description(struct_type, &packed_ddt); if (ret != 0) goto cleanup; memcpy(payload, packed_ddt, packed_ddt_len); unpacked_dt = ompi_ddt_create_from_packed_description(&payload, ompi_proc_local()); free(ptr); if (unpacked_dt != NULL) { printf("\tPASSED\n"); } else { printf("\tFAILED: datatypes don't match\n"); ret = 1; goto cleanup; } cleanup: MPI_Finalize(); return ret; }
/* create the initial fragment, pack header, datatype, and payload (if size fits) and send */ int ompi_osc_pt2pt_sendreq_send(ompi_osc_pt2pt_module_t *module, ompi_osc_pt2pt_sendreq_t *sendreq) { int ret = OMPI_SUCCESS; opal_free_list_item_t *item; ompi_osc_pt2pt_send_header_t *header = NULL; ompi_osc_pt2pt_buffer_t *buffer = NULL; size_t written_data = 0; size_t needed_len = sizeof(ompi_osc_pt2pt_send_header_t); const void *packed_ddt; size_t packed_ddt_len = ompi_ddt_pack_description_length(sendreq->req_target_datatype); /* we always need to send the ddt */ needed_len += packed_ddt_len; if (OMPI_OSC_PT2PT_GET != sendreq->req_type) { needed_len += sendreq->req_origin_bytes_packed; } /* Get a buffer */ OPAL_FREE_LIST_GET(&mca_osc_pt2pt_component.p2p_c_buffers, item, ret); if (NULL == item) { ret = OMPI_ERR_TEMP_OUT_OF_RESOURCE; goto cleanup; } buffer = (ompi_osc_pt2pt_buffer_t*) item; /* verify at least enough space for header */ if (mca_osc_pt2pt_component.p2p_c_eager_size < sizeof(ompi_osc_pt2pt_send_header_t)) { ret = OMPI_ERR_OUT_OF_RESOURCE; goto cleanup; } /* setup buffer */ buffer->cbfunc = ompi_osc_pt2pt_sendreq_send_cb; buffer->cbdata = (void*) sendreq; /* pack header */ header = (ompi_osc_pt2pt_send_header_t*) buffer->payload; written_data += sizeof(ompi_osc_pt2pt_send_header_t); header->hdr_base.hdr_flags = 0; header->hdr_windx = sendreq->req_module->p2p_comm->c_contextid; header->hdr_origin = sendreq->req_module->p2p_comm->c_my_rank; header->hdr_origin_sendreq.pval = (void*) sendreq; header->hdr_origin_tag = 0; header->hdr_target_disp = sendreq->req_target_disp; header->hdr_target_count = sendreq->req_target_count; switch (sendreq->req_type) { case OMPI_OSC_PT2PT_PUT: header->hdr_base.hdr_type = OMPI_OSC_PT2PT_HDR_PUT; #if OMPI_ENABLE_MEM_DEBUG header->hdr_target_op = 0; #endif break; case OMPI_OSC_PT2PT_ACC: header->hdr_base.hdr_type = OMPI_OSC_PT2PT_HDR_ACC; header->hdr_target_op = sendreq->req_op_id; break; case OMPI_OSC_PT2PT_GET: header->hdr_base.hdr_type = OMPI_OSC_PT2PT_HDR_GET; #if OMPI_ENABLE_MEM_DEBUG header->hdr_target_op = 0; #endif break; } /* Set datatype id and / or pack datatype */ ret = ompi_ddt_get_pack_description(sendreq->req_target_datatype, &packed_ddt); if (OMPI_SUCCESS != ret) goto cleanup; memcpy((unsigned char*) buffer->payload + written_data, packed_ddt, packed_ddt_len); written_data += packed_ddt_len; if (OMPI_OSC_PT2PT_GET != sendreq->req_type) { /* if sending data and it fits, pack payload */ if (mca_osc_pt2pt_component.p2p_c_eager_size >= written_data + sendreq->req_origin_bytes_packed) { struct iovec iov; uint32_t iov_count = 1; size_t max_data = sendreq->req_origin_bytes_packed; iov.iov_len = max_data; iov.iov_base = (IOVBASE_TYPE*)((unsigned char*) buffer->payload + written_data); ret = ompi_convertor_pack(&sendreq->req_origin_convertor, &iov, &iov_count, &max_data ); if (ret < 0) { ret = OMPI_ERR_FATAL; goto cleanup; } assert(max_data == sendreq->req_origin_bytes_packed); written_data += max_data; header->hdr_msg_length = sendreq->req_origin_bytes_packed; } else { header->hdr_msg_length = 0; header->hdr_origin_tag = create_send_tag(module); } } else { header->hdr_msg_length = 0; } buffer->len = written_data; #ifdef WORDS_BIGENDIAN header->hdr_base.hdr_flags |= OMPI_OSC_PT2PT_HDR_FLAG_NBO; #elif OMPI_ENABLE_HETEROGENEOUS_SUPPORT if (sendreq->req_target_proc->proc_arch & OMPI_ARCH_ISBIGENDIAN) { header->hdr_base.hdr_flags |= OMPI_OSC_PT2PT_HDR_FLAG_NBO; OMPI_OSC_PT2PT_SEND_HDR_HTON(*header); } #endif /* send fragment */ opal_output_verbose(51, ompi_osc_base_output, "%d sending sendreq to %d", sendreq->req_module->p2p_comm->c_my_rank, sendreq->req_target_rank); ret = MCA_PML_CALL(isend(buffer->payload, buffer->len, MPI_BYTE, sendreq->req_target_rank, -200, MCA_PML_BASE_SEND_STANDARD, module->p2p_comm, &buffer->request)); opal_list_append(&module->p2p_pending_control_sends, &buffer->super.super); goto done; cleanup: if (item != NULL) { OPAL_FREE_LIST_RETURN(&mca_osc_pt2pt_component.p2p_c_buffers, item); } done: return ret; }