1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*-
2  * vim: ts=8 sts=4 sw=4 noexpandtab
3  *
4  *   Copyright (C) 2006 University of Chicago.
5  *   See COPYRIGHT notice in top-level directory.
6  */
7 
8 #include <assert.h>
9 #include "adio.h"
10 #include "adio_extern.h"
11 #include "ad_pvfs2.h"
12 #include "ad_pvfs2_io.h"
13 #include "ad_pvfs2_common.h"
14 
ADIOI_PVFS2_StridedDtypeIO(ADIO_File fd,void * buf,int count,MPI_Datatype datatype,int file_ptr_type,ADIO_Offset offset,ADIO_Status * status,int * error_code,int rw_type)15 int ADIOI_PVFS2_StridedDtypeIO(ADIO_File fd, void *buf, int count,
16 			       MPI_Datatype datatype, int file_ptr_type,
17 			       ADIO_Offset offset, ADIO_Status *status, int
18 			       *error_code,
19 			       int rw_type)
20 {
21     int ret = -1, filetype_is_contig = -1;
22     MPI_Count filetype_size = -1;
23     int num_filetypes = 0, cur_flat_file_reg_off = 0;
24     PVFS_Request tmp_mem_req, mem_req, tmp_file_req, file_req;
25     PVFS_sysresp_io resp_io;
26     ADIO_Offset off = -1, bytes_into_filetype = 0;
27     MPI_Aint filetype_extent = -1, filetype_lb = -1;
28     int i = -1;
29     MPI_Count etype_size;
30     PVFS_size pvfs_disp = -1;
31     ADIOI_Flatlist_node *flat_file_p = ADIOI_Flatlist;
32 
33     /* Use for offseting the PVFS2 filetype */
34     int pvfs_blk = 1;
35     ADIOI_PVFS2_fs *pvfs_fs;
36     static char myname[] = "ADIOI_PVFS2_STRIDED_DTYPE";
37 
38     memset(&tmp_mem_req, 0, sizeof(PVFS_Request));
39     memset(&mem_req, 0, sizeof(PVFS_Request));
40     memset(&tmp_file_req, 0, sizeof(PVFS_Request));
41     memset(&file_req, 0, sizeof(PVFS_Request));
42 
43     pvfs_fs = (ADIOI_PVFS2_fs*)fd->fs_ptr;
44 
45     ADIOI_Datatype_iscontig(fd->filetype, &filetype_is_contig);
46 
47     /* changed below if error */
48     *error_code = MPI_SUCCESS;
49 
50     /* datatype is the memory type
51      * fd->filetype is the file type */
52     MPI_Type_size_x(fd->filetype, &filetype_size);
53     if (filetype_size == 0) {
54         *error_code = MPI_SUCCESS;
55         return -1;
56     }
57     MPI_Type_get_extent(fd->filetype, &filetype_lb, &filetype_extent);
58     MPI_Type_size_x(fd->etype, &etype_size);
59     if (filetype_size == 0) {
60         *error_code = MPI_SUCCESS;
61         return -1;
62     }
63 
64     /* offset is in units of etype relative to the filetype.  We
65      * convert this to off in terms of actual data bytes (the offset
66      * minus the number of bytes that are not used).  We are allowed
67      * to do this since PVFS2 handles offsets with respect to a
68      * file_req in bytes, otherwise we would have to convert into a
69      * pure byte offset as is done in other methods.  Explicit offset
70      * case is handled by using fd->disp and byte-converted off. */
71 
72     pvfs_disp = fd->disp;
73     if (file_ptr_type == ADIO_INDIVIDUAL)
74     {
75 	if (filetype_is_contig)
76 	{
77 	    off = fd->fp_ind - fd->disp;
78 	}
79 	else
80 	{
81 	    int flag = 0;
82 	    /* Should have already been flattened in ADIO_Open*/
83 	    while (flat_file_p->type != fd->filetype)
84 	    {
85 		flat_file_p = flat_file_p->next;
86 	    }
87 	    num_filetypes = -1;
88 	    while (!flag)
89 	    {
90 		num_filetypes++;
91 		for (i = 0; i < flat_file_p->count; i++)
92 		{
93 		    /* Start on a non zero-length region */
94 		    if (flat_file_p->blocklens[i])
95 		    {
96 			if (fd->disp + flat_file_p->indices[i] +
97 			    (num_filetypes * filetype_extent) +
98 			    flat_file_p->blocklens[i] > fd->fp_ind &&
99 			    fd->disp + flat_file_p->indices[i] <=
100 			    fd->fp_ind)
101 			{
102 			    cur_flat_file_reg_off = fd->fp_ind -
103 				(fd->disp + flat_file_p->indices[i] +
104 				 (num_filetypes * filetype_extent));
105 			    flag = 1;
106 			    break;
107 			}
108 			else
109 			    bytes_into_filetype += flat_file_p->blocklens[i];
110 		    }
111 		}
112 	    }
113 	    /* Impossible that we don't find it in this datatype */
114 	    assert(i != flat_file_p->count);
115 	    off = bytes_into_filetype + cur_flat_file_reg_off;
116 	}
117     }
118     else /* ADIO_EXPLICIT */
119     {
120 	off = etype_size * offset;
121     }
122 
123 #ifdef DEBUG_DTYPE
124     fprintf(stderr, "ADIOI_PVFS2_StridedDtypeIO: (fd->fp_ind=%Ld,fd->disp=%Ld,"
125 	    " offset=%Ld),(pvfs_disp=%Ld,off=%Ld)\n",
126 	    fd->fp_ind, fd->disp, offset, pvfs_disp, off);
127 #endif
128 
129 
130     /* Convert the MPI memory and file datatypes into
131      * PVFS2 datatypes */
132     ret = convert_mpi_pvfs2_dtype(&datatype, &tmp_mem_req);
133     if (ret < 0)
134     {
135 	goto error_state;
136     }
137     ret = convert_mpi_pvfs2_dtype(&(fd->filetype), &tmp_file_req);
138     if (ret < 0)
139     {
140 	goto error_state;
141     }
142 
143     ret = PVFS_Request_contiguous(count, tmp_mem_req, &mem_req);
144     if (ret != 0) /* TODO: convert this to MPIO error handling */
145         fprintf(stderr, "ADIOI_PVFS2_stridedDtypeIO: error in final"
146 		" CONTIG memory type\n");
147     PVFS_Request_free(&tmp_mem_req);
148 
149     /* pvfs_disp is used to offset the filetype */
150     ret = PVFS_Request_hindexed(1, &pvfs_blk, &pvfs_disp,
151                                 tmp_file_req, &file_req);
152     if (ret != 0)
153         fprintf(stderr, "ADIOI_PVFS2_StridedDtypeIO: error in final"
154 			" HINDEXED file type\n");
155     PVFS_Request_free(&tmp_file_req);
156 
157     if (rw_type == READ)
158 	ret = PVFS_sys_read(pvfs_fs->object_ref, file_req, off, buf,
159 			    mem_req, &(pvfs_fs->credentials), &resp_io);
160     else
161 	ret = PVFS_sys_write(pvfs_fs->object_ref, file_req, off, buf,
162 			     mem_req, &(pvfs_fs->credentials), &resp_io);
163 
164     if (ret != 0) {
165 	fprintf(stderr, "ADIOI_PVFS2_StridedDtypeIO: Warning - PVFS_sys_"
166 		"read/write returned %d and completed %Ld bytes.\n",
167 		ret, (long long)resp_io.total_completed);
168         *error_code = MPIO_Err_create_code(MPI_SUCCESS,
169                                            MPIR_ERR_RECOVERABLE,
170                                            myname, __LINE__,
171                                            ADIOI_PVFS2_error_convert(ret),
172                                            "Error in PVFS_sys_io \n", 0);
173         goto error_state;
174     }
175 
176     if (file_ptr_type == ADIO_INDIVIDUAL)
177     {
178         fd->fp_ind = off += resp_io.total_completed;
179     }
180 
181   error_state:
182     fd->fp_sys_posn = -1;   /* set it to null. */
183 
184     PVFS_Request_free(&mem_req);
185     PVFS_Request_free(&file_req);
186 
187 #ifdef DEBUG_DTYPE
188     fprintf(stderr, "ADIOI_PVFS2_StridedDtypeIO: "
189             "resp_io.total_completed=%Ld,ret=%d\n",
190 	    resp_io.total_completed, ret);
191 #endif
192 
193 #ifdef HAVE_STATUS_SET_BYTES
194     MPIR_Status_set_bytes(status, datatype, resp_io.total_completed);
195     /* This is a temporary way of filling in status. The right way is to
196      * keep track of how much data was actually acccessed by
197      * ADIOI_BUFFERED operations */
198 #endif
199     return ret;
200 }
201 
202 /* convert_mpi_pvfs2_dtype - Convert a MPI datatype into
203  * a PVFS2 datatype so that we can natively use the PVFS2
204  * datatypes in the PVFS2 I/O calls instead of converting
205  * all datatypes to the hindexed method
206  * return 1  - a leaf node
207  * return 0  - normal return
208  * return -1 - problems */
209 
convert_mpi_pvfs2_dtype(MPI_Datatype * mpi_dtype,PVFS_Request * pvfs_dtype)210 int convert_mpi_pvfs2_dtype(MPI_Datatype *mpi_dtype,
211 			    PVFS_Request *pvfs_dtype)
212 {
213     int num_int = -1, num_addr = -1, num_dtype = -1,
214 	combiner = -1, i = -1, ret = -1, leaf = -1;
215     int *arr_int = NULL;
216     MPI_Aint *arr_addr = NULL;
217     MPI_Datatype *arr_dtype = NULL;
218     PVFS_Request *old_pvfs_dtype = NULL;
219     PVFS_Request *old_pvfs_dtype_arr = NULL;
220     int arr_count = -1;
221     PVFS_size *pvfs_arr_disp = NULL;
222     int *pvfs_arr_len = NULL;
223 
224     MPI_Type_get_envelope(*mpi_dtype,
225 			  &num_int,
226 			  &num_addr,
227 			  &num_dtype,
228 			  &combiner);
229 
230     /* Depending on type of datatype do the following
231      * operations */
232 
233     if (combiner == MPI_COMBINER_NAMED)
234     {
235 	convert_named(mpi_dtype, pvfs_dtype, combiner);
236 	return 1;
237     }
238 
239     /* Allocate space for the arrays necessary for
240      * MPI_Type_get_contents */
241 
242     if ((arr_int = ADIOI_Malloc(sizeof(int)*num_int)) == NULL)
243     {
244 	fprintf(stderr, "Failed to allocate array_int\n");
245 	return -1;
246     }
247     if ((arr_addr = ADIOI_Malloc(sizeof(int)*num_addr)) == NULL)
248     {
249 	ADIOI_Free(arr_int);
250 	fprintf(stderr, "Failed to allocate array_addr\n");
251 	return -1;
252     }
253     if ((arr_dtype = ADIOI_Malloc(sizeof(MPI_Datatype)*num_dtype)) == NULL)
254     {
255 	ADIOI_Free(arr_int);
256 	ADIOI_Free(arr_addr);
257 	fprintf(stderr, "Failed to allocate array_dtypes\n");
258 	return -1;
259     }
260 
261     MPI_Type_get_contents(*mpi_dtype,
262 			  num_int,
263 			  num_addr,
264 			  num_dtype,
265 			  arr_int,
266 			  arr_addr,
267 			  arr_dtype);
268 
269     /* If it's not a predefined datatype, it is either a
270      * derived datatype or a structured datatype */
271 
272     if (combiner != MPI_COMBINER_STRUCT)
273     {
274 	if ((old_pvfs_dtype = ADIOI_Malloc(sizeof(PVFS_Request))) == NULL)
275 	    fprintf(stderr, "convert_mpi_pvfs2_dtype: "
276 		    "Failed to allocate PVFS_Request\n");
277 	switch (combiner)
278 	{
279 	    case MPI_COMBINER_CONTIGUOUS:
280 		leaf = convert_mpi_pvfs2_dtype(&arr_dtype[0], old_pvfs_dtype);
281 		ret = PVFS_Request_contiguous(arr_int[0],
282 					      *old_pvfs_dtype, pvfs_dtype);
283 		break;
284 	    case MPI_COMBINER_VECTOR:
285 		leaf = convert_mpi_pvfs2_dtype(&arr_dtype[0], old_pvfs_dtype);
286 		ret = PVFS_Request_vector(arr_int[0], arr_int[1],
287 					  arr_int[2], *old_pvfs_dtype,
288 					  pvfs_dtype);
289 		break;
290 	    case MPI_COMBINER_HVECTOR:
291 		leaf = convert_mpi_pvfs2_dtype(&arr_dtype[0], old_pvfs_dtype);
292 		ret = PVFS_Request_hvector(arr_int[0], arr_int[1],
293 					   arr_addr[0], *old_pvfs_dtype,
294 					   pvfs_dtype);
295 		break;
296 		/* Both INDEXED and HINDEXED types require PVFS_size
297 		 * address arrays.  Therefore, we need to copy and
298 		 * convert the data from MPI_get_contents() into
299 		 * a PVFS_size buffer */
300 	    case MPI_COMBINER_INDEXED:
301 		leaf = convert_mpi_pvfs2_dtype(&arr_dtype[0], old_pvfs_dtype);
302 		if ((pvfs_arr_disp =
303 			    ADIOI_Malloc(arr_int[0]*sizeof(PVFS_size))) == 0)
304 		{
305 		    fprintf(stderr, "convert_mpi_pvfs2_dtype: "
306 			    "Failed to allocate pvfs_arr_disp\n");
307 		}
308 		for (i = 0; i < arr_int[0]; i++)
309 		{
310 		    pvfs_arr_disp[i] =
311 			(PVFS_size) arr_int[arr_int[0]+1+i];
312 		}
313 		ret = PVFS_Request_indexed(arr_int[0], &arr_int[1],
314 				     pvfs_arr_disp,
315 				     *old_pvfs_dtype, pvfs_dtype);
316 		ADIOI_Free(pvfs_arr_disp);
317 		break;
318 	    case MPI_COMBINER_HINDEXED:
319 		leaf = convert_mpi_pvfs2_dtype(&arr_dtype[0], old_pvfs_dtype);
320 		if ((pvfs_arr_disp =
321 			    ADIOI_Malloc(arr_int[0]*sizeof(PVFS_size))) == 0)
322 		{
323 		    fprintf(stderr, "convert_mpi_pvfs2_dtype: "
324 			    "Failed to allocate pvfs_arr_disp\n");
325 		}
326 		for (i = 0; i < arr_int[0]; i++)
327 		{
328 		    pvfs_arr_disp[i] =
329 			(PVFS_size) arr_addr[i];
330 		}
331 		ret = PVFS_Request_hindexed(arr_int[0], &arr_int[1],
332 				      (int64_t *)&arr_addr[0],
333 				      *old_pvfs_dtype, pvfs_dtype);
334 		ADIOI_Free(pvfs_arr_disp);
335 		break;
336 	    case MPI_COMBINER_DUP:
337                 leaf = convert_mpi_pvfs2_dtype(&arr_dtype[0], old_pvfs_dtype);
338 		ret = PVFS_Request_contiguous(1,
339 					      *old_pvfs_dtype, pvfs_dtype);
340 
341                 break;
342 	    case MPI_COMBINER_INDEXED_BLOCK:
343 		/* No native PVFS2 support for this operation currently */
344 		ADIOI_Free(old_pvfs_dtype);
345 		fprintf(stderr, "convert_mpi_pvfs2_dtype: "
346 			"INDEXED_BLOCK is unsupported\n");
347 		break;
348 	    case MPI_COMBINER_HINDEXED_BLOCK:
349 		/* No native PVFS2 support for this operation currently */
350 		ADIOI_Free(old_pvfs_dtype);
351 		fprintf(stderr, "convert_mpi_pvfs2_dtype: "
352 			"HINDEXED_BLOCK is unsupported\n");
353 		break;
354 	    case MPI_COMBINER_HINDEXED_INTEGER:
355 		ADIOI_Free(old_pvfs_dtype);
356 		fprintf(stderr, "convert_mpi_pvfs2_dtype: "
357 			"HINDEXED_INTEGER is unsupported\n");
358 		break;
359 	    case MPI_COMBINER_STRUCT_INTEGER:
360 		ADIOI_Free(old_pvfs_dtype);
361 		fprintf(stderr, "convert_mpi_pvfs2_dtype: "
362 			"STRUCT_INTEGER is unsupported\n");
363 		break;
364 	    case MPI_COMBINER_SUBARRAY:
365 		ADIOI_Free(old_pvfs_dtype);
366 		fprintf(stderr, "convert_mpi_pvfs2_dtype: "
367 			"SUBARRAY is unsupported\n");
368 		break;
369 	    case MPI_COMBINER_DARRAY:
370 		ADIOI_Free(old_pvfs_dtype);
371 		fprintf(stderr, "convert_mpi_pvfs2_dtype: "
372 			"DARRAY is unsupported\n");
373 		break;
374 	    case MPI_COMBINER_F90_REAL:
375 		ADIOI_Free(old_pvfs_dtype);
376 		fprintf(stderr, "convert_mpi_pvfs2_dtype: "
377 			"F90_REAL is unsupported\n");
378 		break;
379 	    case MPI_COMBINER_F90_COMPLEX:
380 		ADIOI_Free(old_pvfs_dtype);
381 		fprintf(stderr, "convert_mpi_pvfs2_dtype: "
382 			"F90_COMPLEX is unsupported\n");
383 		break;
384 	    case MPI_COMBINER_F90_INTEGER:
385 		ADIOI_Free(old_pvfs_dtype);
386 		fprintf(stderr, "convert_mpi_pvfs2_dtype: "
387 			"F90_INTEGER is unsupported\n");
388 		break;
389 	    case MPI_COMBINER_RESIZED:
390 		ADIOI_Free(old_pvfs_dtype);
391 		fprintf(stderr, "convert_mpi_pvfs2_dtype: "
392 			"RESIZED is unsupported\n");
393 		break;
394 	    default:
395 		break;
396 	}
397 
398 	if (ret != 0)
399 	    fprintf(stderr, "Error in PVFS_Request_* "
400 		    "for a derived datatype\n");
401 
402 #ifdef DEBUG_DTYPE
403 	print_dtype_info(combiner,
404 			 num_int,
405 			 num_addr,
406 			 num_dtype,
407 			 arr_int,
408 			 arr_addr,
409 			 arr_dtype);
410 #endif
411 
412 	if (leaf != 1 && combiner != MPI_COMBINER_DUP)
413 	    MPI_Type_free(&arr_dtype[0]);
414 
415 	ADIOI_Free(arr_int);
416 	ADIOI_Free(arr_addr);
417 	ADIOI_Free(arr_dtype);
418 
419 	PVFS_Request_free(old_pvfs_dtype);
420 	ADIOI_Free(old_pvfs_dtype);
421 
422 	return ret;
423     }
424     else /* MPI_COMBINER_STRUCT */
425     {
426 	MPI_Aint mpi_lb = -1, mpi_extent = -1;
427 	PVFS_offset pvfs_lb = -1;
428 	PVFS_size pvfs_extent = -1;
429 	int has_lb_ub = 0;
430 
431 	/* When converting into a PVFS_Request_struct, we no longer
432 	 * can use MPI_LB and MPI_UB.  Therfore, we have to do the
433 	 * following.
434 	 * We simply ignore all the MPI_LB and MPI_UB types and
435 	 * get the lb and extent and pass it on through a
436 	 * PVFS resized_req */
437 
438 	arr_count = 0;
439 	for (i = 0; i < arr_int[0]; i++)
440 	{
441 	    if (arr_dtype[i] != MPI_LB &&
442 		arr_dtype[i] != MPI_UB)
443 	    {
444 		arr_count++;
445 	    }
446 	}
447 
448 	if (arr_int[0] != arr_count)
449 	{
450 	    MPI_Type_get_extent(*mpi_dtype, &mpi_lb, &mpi_extent);
451 	    pvfs_lb = mpi_lb;
452 	    pvfs_extent = mpi_extent;
453 	    if ((pvfs_arr_len = ADIOI_Malloc(arr_count*sizeof(int)))
454 		== NULL)
455 	    {
456 		fprintf(stderr, "convert_mpi_pvfs2_dtype: "
457 			"Failed to allocate pvfs_arr_len\n");
458 	    }
459 	    has_lb_ub = 1;
460 	}
461 
462 	if ((old_pvfs_dtype_arr
463 	     = ADIOI_Malloc(arr_count*sizeof(PVFS_Request))) == NULL)
464 	    fprintf(stderr, "convert_mpi_pvfs2_dtype: "
465 		    "Failed to allocate PVFS_Requests\n");
466 
467 	if ((pvfs_arr_disp = ADIOI_Malloc(arr_count*sizeof(PVFS_size)))
468 	    == NULL)
469 	{
470 	    fprintf(stderr, "convert_mpi_pvfs2_dtype: "
471 		    "Failed to allocate pvfs_arr_disp\n");
472 	}
473 
474 	arr_count = 0;
475 	for (i = 0; i < arr_int[0]; i++)
476 	{
477 	    if (arr_dtype[i] != MPI_LB &&
478 		arr_dtype[i] != MPI_UB)
479 	    {
480 		leaf = convert_mpi_pvfs2_dtype(
481 		    &arr_dtype[i], &old_pvfs_dtype_arr[arr_count]);
482 		if (leaf != 1)
483 		    MPI_Type_free(&arr_dtype[i]);
484 		pvfs_arr_disp[arr_count] =
485 		    (PVFS_size) arr_addr[i];
486 		if (has_lb_ub)
487 		{
488 		    pvfs_arr_len[arr_count] =
489 			arr_int[i+1];
490 		}
491 		arr_count++;
492 	    }
493 	}
494 
495 	/* If a MPI_UB or MPI_LB did exist, we have to
496 	 * resize the datatype */
497 	if (has_lb_ub)
498 	{
499 	    PVFS_Request *tmp_pvfs_dtype = NULL;
500 	    if ((tmp_pvfs_dtype = ADIOI_Malloc(sizeof(PVFS_Request))) == NULL)
501 		fprintf(stderr, "convert_mpi_pvfs2_dtype: "
502 			"Failed to allocate PVFS_Request\n");
503 
504 	    ret = PVFS_Request_struct(arr_count, pvfs_arr_len,
505 				      pvfs_arr_disp,
506 				      old_pvfs_dtype_arr, tmp_pvfs_dtype);
507 	    if (ret != 0)
508 		fprintf(stderr, "Error in PVFS_Request_struct\n");
509 
510 	    arr_count = 0;
511 	    for (i = 0; i < arr_int[0]; i++)
512 	    {
513 		if (arr_dtype[i] != MPI_LB &&
514 		    arr_dtype[i] != MPI_UB)
515 		{
516 		    PVFS_Request_free(&old_pvfs_dtype_arr[arr_count]);
517 		    arr_count++;
518 		}
519 	    }
520 
521 #ifdef DEBUG_DTYPE
522 	    fprintf(stderr, "STRUCT(WITHOUT %d LB or UB)(%d,[",
523 		    arr_int[0] - arr_count, arr_count);
524 	    for (i = 0; i < arr_count; i++)
525 		fprintf(stderr, "(%d,%Ld) ",
526 			pvfs_arr_len[i],
527 			pvfs_arr_disp[i]);
528 	    fprintf(stderr, "]\n");
529 	    fprintf(stderr, "RESIZED(LB = %Ld, EXTENT = %Ld)\n",
530 		    pvfs_lb, pvfs_extent);
531 #endif
532 	    ret = PVFS_Request_resized(*tmp_pvfs_dtype,
533 				       pvfs_lb, pvfs_extent, pvfs_dtype);
534 	    if (ret != 0)
535 		fprintf(stderr, "Error in PVFS_Request_resize\n");
536 
537 	    PVFS_Request_free(tmp_pvfs_dtype);
538 	    ADIOI_Free(tmp_pvfs_dtype);
539 	}
540 	else /* No MPI_LB or MPI_UB datatypes */
541 	{
542 	    ret = PVFS_Request_struct(arr_int[0], &arr_int[1],
543 				      pvfs_arr_disp,
544 				      old_pvfs_dtype_arr, pvfs_dtype);
545 	    if (ret != 0)
546 		fprintf(stderr, "Error in PVFS_Request_struct\n");
547 
548 	    for (i = 0; i < arr_int[0]; i++)
549 	    {
550 		if (arr_dtype[i] != MPI_LB &&
551 		    arr_dtype[i] != MPI_UB)
552 		    PVFS_Request_free(&old_pvfs_dtype_arr[i]);
553 	    }
554 
555 #ifdef DEBUG_DTYPE
556 	    print_dtype_info(combiner,
557 			     num_int,
558 			     num_addr,
559 			     num_dtype,
560 			     arr_int,
561 			     arr_addr,
562 			     arr_dtype);
563 #endif
564 	}
565 
566 	ADIOI_Free(arr_int);
567 	ADIOI_Free(arr_addr);
568 	ADIOI_Free(arr_dtype);
569 
570 	ADIOI_Free(old_pvfs_dtype_arr);
571 	ADIOI_Free(pvfs_arr_disp);
572 	ADIOI_Free(pvfs_arr_len);
573 
574 	return ret;
575     }
576 
577     /* Shouldn't have gotten here */
578     fprintf(stderr, "convert_mpi_pvfs2_dtype:  SERIOUS ERROR\n");
579     return -1;
580 }
581 
convert_named(MPI_Datatype * mpi_dtype,PVFS_Request * pvfs_dtype,int combiner)582 int convert_named(MPI_Datatype *mpi_dtype,
583 		  PVFS_Request *pvfs_dtype, int combiner)
584 {
585     int ret = -1;
586 #ifdef DEBUG_DTYPE
587     fprintf(stderr, "NAMED");
588 #endif
589 
590     if (MPI_CHAR == *mpi_dtype)
591     {
592 	    ret = PVFS_Request_contiguous(1, PVFS_CHAR, pvfs_dtype);
593 #ifdef DEBUG_DTYPE
594 	    fprintf(stderr, "-MPI_CHAR\n");
595 #endif
596     }
597     else if ( MPI_BYTE == *mpi_dtype )
598     {
599             ret = PVFS_Request_contiguous(1, PVFS_BYTE, pvfs_dtype);
600 #ifdef DEBUG_DTYPE
601             fprintf(stderr, "-MPI_BYTE\n");
602 #endif
603     }
604     else if ( MPI_SHORT == *mpi_dtype )
605     {
606             ret = PVFS_Request_contiguous(1, PVFS_SHORT, pvfs_dtype);
607 #ifdef DEBUG_DTYPE
608             fprintf(stderr, "-MPI_SHORT\n");
609 #endif
610     }
611     else if ( MPI_INT == *mpi_dtype )
612     {
613             ret = PVFS_Request_contiguous(1, PVFS_INT, pvfs_dtype);
614 #ifdef DEBUG_DTYPE
615             fprintf(stderr, "-MPI_INT\n");
616 #endif
617     }
618     else if ( MPI_LONG == *mpi_dtype )
619     {
620             ret = PVFS_Request_contiguous(1, PVFS_LONG, pvfs_dtype);
621 #ifdef DEBUG_DTYPE
622             fprintf(stderr, "-MPI_LONG\n");
623 #endif
624     }
625     else if ( MPI_FLOAT == *mpi_dtype )
626     {
627 	    ret  = PVFS_Request_contiguous(1, PVFS_FLOAT, pvfs_dtype);
628 #ifdef DEBUG_DTYPE
629 	    fprintf(stderr, "-MPI_FLOAT\n");
630 #endif
631     }
632     else if ( MPI_DOUBLE == *mpi_dtype )
633     {
634 	    ret = PVFS_Request_contiguous(1, PVFS_DOUBLE, pvfs_dtype);
635 #ifdef DEBUG_DTYPE
636 	    fprintf(stderr, "-MPI_DOUBLE\n");
637 #endif
638     }
639     else if ( MPI_UNSIGNED_CHAR == *mpi_dtype )
640     {
641 	    ret = PVFS_Request_contiguous(1, PVFS_UNSIGNED_CHAR, pvfs_dtype);
642 #ifdef DEBUG_DTYPE
643 	    fprintf(stderr, "-MPI_UNSIGNED_CHAR\n");
644 #endif
645     }
646     else if ( MPI_UNSIGNED_SHORT == *mpi_dtype )
647     {
648 	    ret = PVFS_Request_contiguous(1, PVFS_UNSIGNED, pvfs_dtype);
649 #ifdef DEBUG_DTYPE
650 	    fprintf(stderr, "-MPI_UNSIGNED_SHORT\n");
651 #endif
652     }
653     else if ( MPI_UNSIGNED == *mpi_dtype )
654     {
655 	    ret = PVFS_Request_contiguous(1, PVFS_UNSIGNED, pvfs_dtype);
656 #ifdef DEBUG_DTYPE
657 	    fprintf(stderr, "-MPI_SHORT\n");
658 #endif
659     }
660     else if ( MPI_UNSIGNED_LONG == *mpi_dtype )
661     {
662 	    ret = PVFS_Request_contiguous(1, PVFS_UNSIGNED_LONG, pvfs_dtype);
663 #ifdef DEBUG_DTYPE
664 	    fprintf(stderr, "-MPI_UNSIGNED_LONG\n");
665 #endif
666     }
667     else if ( MPI_LONG_DOUBLE == *mpi_dtype )
668     {
669 	    ret = PVFS_Request_contiguous(1, PVFS_LONG_DOUBLE, pvfs_dtype);
670 #ifdef DEBUG_DTYPE
671 	    fprintf(stderr, "-MPI_LONG_DOUBLE\n");
672 #endif
673     }
674     else
675     {
676 	    fprintf(stderr, "convert_named: predefined type not found");
677 	    return -1;
678     }
679     if (ret != 0)
680 	fprintf(stderr, "convert_named: Datatype creation failed\n");
681     return ret;
682 }
683 
print_dtype_info(int combiner,int num_int,int num_addr,int num_dtype,int * arr_int,MPI_Aint * arr_addr,MPI_Datatype * arr_dtype)684 void print_dtype_info(int combiner,
685 		      int num_int,
686 		      int num_addr,
687 		      int num_dtype,
688 		      int *arr_int,
689 		      MPI_Aint *arr_addr,
690 		      MPI_Datatype *arr_dtype)
691 {
692     int i = -1;
693     switch (combiner)
694     {
695 	case MPI_COMBINER_CONTIGUOUS:
696 	    fprintf(stderr, "CONTIG(%d)\n", arr_int[0]);
697 	    break;
698 	case MPI_COMBINER_VECTOR:
699 	    fprintf(stderr, "VECTOR(%d,%d,%d)\n",
700 		    arr_int[0], arr_int[1], arr_int[2]);
701 	    break;
702 	case MPI_COMBINER_HVECTOR:
703 	    fprintf(stderr, "HVECTOR(%d,%d,%ld)\n",
704 		    arr_int[0], arr_int[1],arr_addr[0]);
705 	    break;
706 	case MPI_COMBINER_INDEXED:
707 	    fprintf(stderr, "INDEXED(%d,[",
708 		    arr_int[0]);
709 	    for (i = 0; i < arr_int[0]; i++)
710 		fprintf(stderr, "(%d,%d) ",
711 			arr_int[1+i],
712 			arr_int[arr_int[0]+1+i]);
713 	    fprintf(stderr, "]\n");
714 	    break;
715 	case MPI_COMBINER_HINDEXED:
716 	    fprintf(stderr, "HINDEXED(%d,[",
717 		    arr_int[0]);
718 	    for (i = 0; i < arr_int[0]; i++)
719 		fprintf(stderr, "(%d,%lld) ",
720 			arr_int[1+i],
721 			(long long)arr_addr[i]);
722 	    fprintf(stderr, "]\n");
723 	    break;
724 	case MPI_COMBINER_STRUCT:
725 	    fprintf(stderr, "STRUCT(%d,[",
726 		    arr_int[0]);
727 	    for (i = 0; i < arr_int[0]; i++)
728 		fprintf(stderr, "(%d,%lld) ",
729 			arr_int[1+i],
730 			(long long) arr_addr[i]);
731 	    fprintf(stderr, "]\n");
732 	    break;
733 	case MPI_COMBINER_DUP:
734 	    fprintf(stderr, "DUP\n");
735 	    break;
736 	default:
737 	    fprintf(stderr, "no available information on this datatype");
738     }
739 }
740