/* this is a stupid first approach, fix it later - WBL */ static int PVFS_Request_indexed_block(int32_t count, int32_t blocklength, PVFS_size * displacements, PVFS_Request oldreq, PVFS_Request * newreq) { int i; int32_t *blocklengths; blocklengths = alloca(count * sizeof(int32_t)); for (i = 0; i < count; i++) blocklengths[i] = blocklength; return PVFS_Request_indexed(count, blocklengths, displacements, oldreq, newreq); }
int convert_mpi_pvfs2_dtype(MPI_Datatype *mpi_dtype, PVFS_Request *pvfs_dtype) { int num_int = -1, num_addr = -1, num_dtype = -1, combiner = -1, i = -1, ret = -1, leaf = -1; int *arr_int = NULL; MPI_Aint *arr_addr = NULL; MPI_Datatype *arr_dtype = NULL; PVFS_Request *old_pvfs_dtype = NULL; PVFS_Request *old_pvfs_dtype_arr = NULL; int arr_count = -1; PVFS_size *pvfs_arr_disp = NULL; int *pvfs_arr_len = NULL; MPI_Type_get_envelope(*mpi_dtype, &num_int, &num_addr, &num_dtype, &combiner); /* Depending on type of datatype do the following * operations */ if (combiner == MPI_COMBINER_NAMED) { convert_named(mpi_dtype, pvfs_dtype, combiner); return 1; } /* Allocate space for the arrays necessary for * MPI_Type_get_contents */ if ((arr_int = ADIOI_Malloc(sizeof(int)*num_int)) == NULL) { fprintf(stderr, "Failed to allocate array_int\n"); return -1; } if ((arr_addr = ADIOI_Malloc(sizeof(int)*num_addr)) == NULL) { ADIOI_Free(arr_int); fprintf(stderr, "Failed to allocate array_addr\n"); return -1; } if ((arr_dtype = ADIOI_Malloc(sizeof(MPI_Datatype)*num_dtype)) == NULL) { ADIOI_Free(arr_int); ADIOI_Free(arr_addr); fprintf(stderr, "Failed to allocate array_dtypes\n"); return -1; } MPI_Type_get_contents(*mpi_dtype, num_int, num_addr, num_dtype, arr_int, arr_addr, arr_dtype); /* If it's not a predefined datatype, it is either a * derived datatype or a structured datatype */ if (combiner != MPI_COMBINER_STRUCT) { if ((old_pvfs_dtype = ADIOI_Malloc(sizeof(PVFS_Request))) == NULL) fprintf(stderr, "convert_mpi_pvfs2_dtype: " "Failed to allocate PVFS_Request\n"); switch (combiner) { case MPI_COMBINER_CONTIGUOUS: leaf = convert_mpi_pvfs2_dtype(&arr_dtype[0], old_pvfs_dtype); ret = PVFS_Request_contiguous(arr_int[0], *old_pvfs_dtype, pvfs_dtype); break; case MPI_COMBINER_VECTOR: leaf = convert_mpi_pvfs2_dtype(&arr_dtype[0], old_pvfs_dtype); ret = PVFS_Request_vector(arr_int[0], arr_int[1], arr_int[2], *old_pvfs_dtype, pvfs_dtype); break; case MPI_COMBINER_HVECTOR: leaf = convert_mpi_pvfs2_dtype(&arr_dtype[0], old_pvfs_dtype); ret = PVFS_Request_hvector(arr_int[0], arr_int[1], arr_addr[0], *old_pvfs_dtype, pvfs_dtype); break; /* Both INDEXED and HINDEXED types require PVFS_size * address arrays. Therefore, we need to copy and * convert the data from MPI_get_contents() into * a PVFS_size buffer */ case MPI_COMBINER_INDEXED: leaf = convert_mpi_pvfs2_dtype(&arr_dtype[0], old_pvfs_dtype); if ((pvfs_arr_disp = ADIOI_Malloc(arr_int[0]*sizeof(PVFS_size))) == 0) { fprintf(stderr, "convert_mpi_pvfs2_dtype: " "Failed to allocate pvfs_arr_disp\n"); } for (i = 0; i < arr_int[0]; i++) { pvfs_arr_disp[i] = (PVFS_size) arr_int[arr_int[0]+1+i]; } ret = PVFS_Request_indexed(arr_int[0], &arr_int[1], pvfs_arr_disp, *old_pvfs_dtype, pvfs_dtype); ADIOI_Free(pvfs_arr_disp); break; case MPI_COMBINER_HINDEXED: leaf = convert_mpi_pvfs2_dtype(&arr_dtype[0], old_pvfs_dtype); if ((pvfs_arr_disp = ADIOI_Malloc(arr_int[0]*sizeof(PVFS_size))) == 0) { fprintf(stderr, "convert_mpi_pvfs2_dtype: " "Failed to allocate pvfs_arr_disp\n"); } for (i = 0; i < arr_int[0]; i++) { pvfs_arr_disp[i] = (PVFS_size) arr_addr[i]; } ret = PVFS_Request_hindexed(arr_int[0], &arr_int[1], (int64_t *)&arr_addr[0], *old_pvfs_dtype, pvfs_dtype); ADIOI_Free(pvfs_arr_disp); break; case MPI_COMBINER_DUP: leaf = convert_mpi_pvfs2_dtype(&arr_dtype[0], old_pvfs_dtype); ret = PVFS_Request_contiguous(1, *old_pvfs_dtype, pvfs_dtype); break; case MPI_COMBINER_INDEXED_BLOCK: /* No native PVFS2 support for this operation currently */ ADIOI_Free(old_pvfs_dtype); fprintf(stderr, "convert_mpi_pvfs2_dtype: " "INDEXED_BLOCK is unsupported\n"); break; case MPI_COMBINER_HINDEXED_BLOCK: /* No native PVFS2 support for this operation currently */ ADIOI_Free(old_pvfs_dtype); fprintf(stderr, "convert_mpi_pvfs2_dtype: " "HINDEXED_BLOCK is unsupported\n"); break; case MPI_COMBINER_HINDEXED_INTEGER: ADIOI_Free(old_pvfs_dtype); fprintf(stderr, "convert_mpi_pvfs2_dtype: " "HINDEXED_INTEGER is unsupported\n"); break; case MPI_COMBINER_STRUCT_INTEGER: ADIOI_Free(old_pvfs_dtype); fprintf(stderr, "convert_mpi_pvfs2_dtype: " "STRUCT_INTEGER is unsupported\n"); break; case MPI_COMBINER_SUBARRAY: ADIOI_Free(old_pvfs_dtype); fprintf(stderr, "convert_mpi_pvfs2_dtype: " "SUBARRAY is unsupported\n"); break; case MPI_COMBINER_DARRAY: ADIOI_Free(old_pvfs_dtype); fprintf(stderr, "convert_mpi_pvfs2_dtype: " "DARRAY is unsupported\n"); break; case MPI_COMBINER_F90_REAL: ADIOI_Free(old_pvfs_dtype); fprintf(stderr, "convert_mpi_pvfs2_dtype: " "F90_REAL is unsupported\n"); break; case MPI_COMBINER_F90_COMPLEX: ADIOI_Free(old_pvfs_dtype); fprintf(stderr, "convert_mpi_pvfs2_dtype: " "F90_COMPLEX is unsupported\n"); break; case MPI_COMBINER_F90_INTEGER: ADIOI_Free(old_pvfs_dtype); fprintf(stderr, "convert_mpi_pvfs2_dtype: " "F90_INTEGER is unsupported\n"); break; case MPI_COMBINER_RESIZED: ADIOI_Free(old_pvfs_dtype); fprintf(stderr, "convert_mpi_pvfs2_dtype: " "RESIZED is unsupported\n"); break; default: break; } if (ret != 0) fprintf(stderr, "Error in PVFS_Request_* " "for a derived datatype\n"); #ifdef DEBUG_DTYPE print_dtype_info(combiner, num_int, num_addr, num_dtype, arr_int, arr_addr, arr_dtype); #endif if (leaf != 1 && combiner != MPI_COMBINER_DUP) MPI_Type_free(&arr_dtype[0]); ADIOI_Free(arr_int); ADIOI_Free(arr_addr); ADIOI_Free(arr_dtype); PVFS_Request_free(old_pvfs_dtype); ADIOI_Free(old_pvfs_dtype); return ret; } else /* MPI_COMBINER_STRUCT */ { MPI_Aint mpi_lb = -1, mpi_extent = -1; PVFS_offset pvfs_lb = -1; PVFS_size pvfs_extent = -1; int has_lb_ub = 0; /* When converting into a PVFS_Request_struct, we no longer * can use MPI_LB and MPI_UB. Therfore, we have to do the * following. * We simply ignore all the MPI_LB and MPI_UB types and * get the lb and extent and pass it on through a * PVFS resized_req */ arr_count = 0; for (i = 0; i < arr_int[0]; i++) { if (arr_dtype[i] != MPI_LB && arr_dtype[i] != MPI_UB) { arr_count++; } } if (arr_int[0] != arr_count) { MPI_Type_get_extent(*mpi_dtype, &mpi_lb, &mpi_extent); pvfs_lb = mpi_lb; pvfs_extent = mpi_extent; if ((pvfs_arr_len = ADIOI_Malloc(arr_count*sizeof(int))) == NULL) { fprintf(stderr, "convert_mpi_pvfs2_dtype: " "Failed to allocate pvfs_arr_len\n"); } has_lb_ub = 1; } if ((old_pvfs_dtype_arr = ADIOI_Malloc(arr_count*sizeof(PVFS_Request))) == NULL) fprintf(stderr, "convert_mpi_pvfs2_dtype: " "Failed to allocate PVFS_Requests\n"); if ((pvfs_arr_disp = ADIOI_Malloc(arr_count*sizeof(PVFS_size))) == NULL) { fprintf(stderr, "convert_mpi_pvfs2_dtype: " "Failed to allocate pvfs_arr_disp\n"); } arr_count = 0; for (i = 0; i < arr_int[0]; i++) { if (arr_dtype[i] != MPI_LB && arr_dtype[i] != MPI_UB) { leaf = convert_mpi_pvfs2_dtype( &arr_dtype[i], &old_pvfs_dtype_arr[arr_count]); if (leaf != 1) MPI_Type_free(&arr_dtype[i]); pvfs_arr_disp[arr_count] = (PVFS_size) arr_addr[i]; if (has_lb_ub) { pvfs_arr_len[arr_count] = arr_int[i+1]; } arr_count++; } } /* If a MPI_UB or MPI_LB did exist, we have to * resize the datatype */ if (has_lb_ub) { PVFS_Request *tmp_pvfs_dtype = NULL; if ((tmp_pvfs_dtype = ADIOI_Malloc(sizeof(PVFS_Request))) == NULL) fprintf(stderr, "convert_mpi_pvfs2_dtype: " "Failed to allocate PVFS_Request\n"); ret = PVFS_Request_struct(arr_count, pvfs_arr_len, pvfs_arr_disp, old_pvfs_dtype_arr, tmp_pvfs_dtype); if (ret != 0) fprintf(stderr, "Error in PVFS_Request_struct\n"); arr_count = 0; for (i = 0; i < arr_int[0]; i++) { if (arr_dtype[i] != MPI_LB && arr_dtype[i] != MPI_UB) { PVFS_Request_free(&old_pvfs_dtype_arr[arr_count]); arr_count++; } } #ifdef DEBUG_DTYPE fprintf(stderr, "STRUCT(WITHOUT %d LB or UB)(%d,[", arr_int[0] - arr_count, arr_count); for (i = 0; i < arr_count; i++) fprintf(stderr, "(%d,%Ld) ", pvfs_arr_len[i], pvfs_arr_disp[i]); fprintf(stderr, "]\n"); fprintf(stderr, "RESIZED(LB = %Ld, EXTENT = %Ld)\n", pvfs_lb, pvfs_extent); #endif ret = PVFS_Request_resized(*tmp_pvfs_dtype, pvfs_lb, pvfs_extent, pvfs_dtype); if (ret != 0) fprintf(stderr, "Error in PVFS_Request_resize\n"); PVFS_Request_free(tmp_pvfs_dtype); ADIOI_Free(tmp_pvfs_dtype); } else /* No MPI_LB or MPI_UB datatypes */ { ret = PVFS_Request_struct(arr_int[0], &arr_int[1], pvfs_arr_disp, old_pvfs_dtype_arr, pvfs_dtype); if (ret != 0) fprintf(stderr, "Error in PVFS_Request_struct\n"); for (i = 0; i < arr_int[0]; i++) { if (arr_dtype[i] != MPI_LB && arr_dtype[i] != MPI_UB) PVFS_Request_free(&old_pvfs_dtype_arr[i]); } #ifdef DEBUG_DTYPE print_dtype_info(combiner, num_int, num_addr, num_dtype, arr_int, arr_addr, arr_dtype); #endif } ADIOI_Free(arr_int); ADIOI_Free(arr_addr); ADIOI_Free(arr_dtype); ADIOI_Free(old_pvfs_dtype_arr); ADIOI_Free(pvfs_arr_disp); ADIOI_Free(pvfs_arr_len); return ret; } /* Shouldn't have gotten here */ fprintf(stderr, "convert_mpi_pvfs2_dtype: SERIOUS ERROR\n"); return -1; }
/* * Parameters: none * Returns 0 on success and -1 on failure (ie - the segment offsets * were not calcuated correctly by Request_indexed */ static int test_write(void){ int i; PINT_Request *r1; PINT_Request *r2; PINT_Request_state *rs1; PINT_Request_state *rs2; PINT_request_file_data rf1; PINT_request_file_data rf2; PINT_Request_result seg1; /* PVFS_Process_request arguments */ int retval; int32_t blocklength = 10*1024*1024; /* 10M */ /* Used for calculating correct offset values */ int32_t tmpOff = 0; int32_t stripesize = 65536; /* set up two requests, both at offset 0 */ PVFS_size displacement = 0; /* first at offset zero */ PVFS_Request_indexed(1, &blocklength, &displacement, PVFS_BYTE, &r1); PVFS_Request_indexed(1, &blocklength, &displacement, PVFS_BYTE, &r2); /* set up two request states */ rs1 = PINT_new_request_state(r1); rs2 = PINT_new_request_state(r2); /* set up file data for first request */ rf1.server_nr = 0; rf1.server_ct = 3; rf1.fsize = 8454144; rf1.dist = PINT_dist_create("simple_stripe"); rf1.extend_flag = 0; PINT_dist_lookup(rf1.dist); /* file data for second request is the same, except the file * will have grown by 10M */ rf2.server_nr = 0; rf2.server_ct = 3; rf2.fsize = 8454144; rf2.dist = PINT_dist_create("simple_stripe"); rf2.extend_flag = 0; PINT_dist_lookup(rf2.dist); /* set up result struct */ seg1.offset_array = (int64_t *)malloc(SEGMAX * sizeof(int64_t)); seg1.size_array = (int64_t *)malloc(SEGMAX * sizeof(int64_t)); seg1.bytemax = BYTEMAX; seg1.segmax = SEGMAX; seg1.bytes = 0; seg1.segs = 0; /* Turn on debugging gossip_enable_stderr(); gossip_set_debug_mask(1,REQUEST_DEBUG); */ do { seg1.bytes = 0; seg1.segs = 0; /* process request */ retval = PINT_process_request(rs1, NULL, &rf1, &seg1, PINT_SERVER); if(retval >= 0) { /* printf("results of PINT_Process_request(PINT_SERVER):\n"); printf("%d segments with %lld bytes\n", seg1.segs, seg1.bytes); */ for(i=0; i<seg1.segs; i++) { if( (blocklength/3) != (int)seg1.size_array[i]){ printf("segment %d size is %d but should be %d\n", i, (int)seg1.size_array[i],blocklength/3); } } } } while(!PINT_REQUEST_DONE(rs1) && retval >= 0); if(retval < 0) { fprintf(stderr, "Error: PINT_Process_request() failure.\n"); return(-1); } if(PINT_REQUEST_DONE(rs1)) { /* printf("**** first request done.\n"); */ } tmpOff = 0; do { seg1.bytes = 0; seg1.segs = 0; /* process request */ retval = PINT_process_request(rs2, NULL, &rf2, &seg1, PINT_CLIENT); if(retval >= 0) { for(i=0; i<seg1.segs; i++, (tmpOff += stripesize*3)) { if(stripesize != (int)seg1.size_array[i]){ printf("segment %d's size is %d but should be %d\n", i,(int)seg1.size_array[i],stripesize); return -1; } else if(tmpOff != (int)seg1.offset_array[i]){ printf("segment %d's offset is %d but should be %d\n", i,(int)seg1.offset_array[i],tmpOff); return -1; } } } } while(!PINT_REQUEST_DONE(rs2) && retval >= 0); if(retval < 0) { fprintf(stderr, "Error: PINT_Process_request() failure.\n"); return(-1); } if(PINT_REQUEST_DONE(rs2)) { /* printf("**** second request done.\n"); */ } return 0; }