⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ad_bgl_wrcoll.c

📁 fortran并行计算包
💻 C
📖 第 1 页 / 共 4 页
字号:
/* ---------------------------------------------------------------- *//* (C)Copyright IBM Corp.  2007, 2008                               *//* ---------------------------------------------------------------- *//** * \file ad_bgl_wrcoll.c * \brief ??? *//* -*- Mode: C; c-basic-offset:4 ; -*- *//*  *   Copyright (C) 1997 University of Chicago.  *   See COPYRIGHT notice in top-level directory. */#include "adio.h"#include "adio_extern.h"#include "ad_bgl.h"#include "ad_bgl_pset.h"#include "ad_bgl_aggrs.h"#ifdef PROFILE#include "mpe.h"#endif/* prototypes of functions used for collective writes only. */static void ADIOI_Exch_and_write(ADIO_File fd, void *buf, MPI_Datatype                         datatype, int nprocs, int myrank, ADIOI_Access                         *others_req, ADIO_Offset *offset_list,                         int *len_list, int contig_access_count, ADIO_Offset                         min_st_offset, ADIO_Offset fd_size,                         ADIO_Offset *fd_start, ADIO_Offset *fd_end,                         int *buf_idx, int *error_code);static void ADIOI_W_Exchange_data(ADIO_File fd, void *buf, char *write_buf,                         ADIOI_Flatlist_node *flat_buf, ADIO_Offset                          *offset_list, int *len_list, int *send_size,                          int *recv_size, ADIO_Offset off, int size,                         int *count, int *start_pos, int *partial_recv,                          int *sent_to_proc, int nprocs,                          int myrank, int                         buftype_is_contig, int contig_access_count,                         ADIO_Offset min_st_offset, ADIO_Offset fd_size,                         ADIO_Offset *fd_start, ADIO_Offset *fd_end,                          ADIOI_Access *others_req,                          int *send_buf_idx, int *curr_to_proc,                         int *done_to_proc, int *hole, int iter,                          MPI_Aint buftype_extent, int *buf_idx, int *error_code);static void ADIOI_W_Exchange_data_alltoallv(		ADIO_File fd, void *buf, 		char *write_buf,					/* 1 */		ADIOI_Flatlist_node *flat_buf, 		ADIO_Offset *offset_list, 		int *len_list, int *send_size, int *recv_size, 		ADIO_Offset off, int size,				/* 2 */		int *count, int *start_pos, int *partial_recv,		int *sent_to_proc, int nprocs, int myrank, 		int buftype_is_contig, int contig_access_count,		ADIO_Offset min_st_offset,		ADIO_Offset fd_size,		ADIO_Offset *fd_start, 		ADIO_Offset *fd_end,		ADIOI_Access *others_req,		int *send_buf_idx, int *curr_to_proc,			/* 3 */		int *done_to_proc, int *hole, 				/* 4 */		int iter, MPI_Aint buftype_extent, int *buf_idx,		int *error_code);static void ADIOI_Fill_send_buffer(ADIO_File fd, void *buf, ADIOI_Flatlist_node                           *flat_buf, char **send_buf, ADIO_Offset                            *offset_list, int *len_list, int *send_size,                            MPI_Request *requests, int *sent_to_proc,                            int nprocs, int myrank,                            int contig_access_count, ADIO_Offset                           min_st_offset, ADIO_Offset fd_size,                           ADIO_Offset *fd_start, ADIO_Offset *fd_end,                            int *send_buf_idx, int *curr_to_proc,                            int *done_to_proc, int iter,                            MPI_Aint buftype_extent);static void ADIOI_Fill_send_buffer_nosend(ADIO_File fd, void *buf, ADIOI_Flatlist_node                           *flat_buf, char **send_buf, ADIO_Offset                            *offset_list, int *len_list, int *send_size,                            MPI_Request *requests, int *sent_to_proc,                            int nprocs, int myrank,                            int contig_access_count, ADIO_Offset                           min_st_offset, ADIO_Offset fd_size,                           ADIO_Offset *fd_start, ADIO_Offset *fd_end,                            int *send_buf_idx, int *curr_to_proc,                            int *done_to_proc, int iter,                            MPI_Aint buftype_extent);static void ADIOI_Heap_merge(ADIOI_Access *others_req, int *count,                       ADIO_Offset *srt_off, int *srt_len, int *start_pos,                      int nprocs, int nprocs_recv, int total_elements);void ADIOI_BGL_WriteStridedColl(ADIO_File fd, void *buf, int count,                       MPI_Datatype datatype, int file_ptr_type,                       ADIO_Offset offset, ADIO_Status *status, int                       *error_code){/* Uses a generalized version of the extended two-phase method described   in "An Extended Two-Phase Method for Accessing Sections of    Out-of-Core Arrays", Rajeev Thakur and Alok Choudhary,   Scientific Programming, (5)4:301--317, Winter 1996.    http://www.mcs.anl.gov/home/thakur/ext2ph.ps */    ADIOI_Access *my_req;     /* array of nprocs access structures, one for each other process in       whose file domain this process's request lies */        ADIOI_Access *others_req;    /* array of nprocs access structures, one for each other process       whose request lies in this process's file domain. */    int i, filetype_is_contig, nprocs, nprocs_for_coll, myrank;    int contig_access_count=0, interleave_count = 0, buftype_is_contig;    int *count_my_req_per_proc, count_my_req_procs, count_others_req_procs;    ADIO_Offset orig_fp, start_offset, end_offset, fd_size, min_st_offset, off;    ADIO_Offset *offset_list = NULL, *st_offsets = NULL, *fd_start = NULL,	*fd_end = NULL, *end_offsets = NULL;    ADIO_Offset *bgl_offsets0 = NULL, *bgl_offsets = NULL;    int  ii;    int *buf_idx = NULL, *len_list = NULL;    double io_time = 0, all_time, max_all_time;    double tstep1, max_tstep1;    double tstep1_1, max_tstep1_1;    double tstep1_2, max_tstep1_2;    double tstep1_3, max_tstep1_3;    double tstep2, max_tstep2;    double tstep3, max_tstep3;    double tstep4, max_tstep4;    double sum_sz;#if BGL_PROFILE     BGLMPIO_T_CIO_RESET( 0, w )#endif#ifdef PROFILE	MPE_Log_event(13, 0, "start computation");#endif    MPI_Comm_size(fd->comm, &nprocs);    MPI_Comm_rank(fd->comm, &myrank);/* the number of processes that actually perform I/O, nprocs_for_coll, * is stored in the hints off the ADIO_File structure */    nprocs_for_coll = fd->hints->cb_nodes;    orig_fp = fd->fp_ind;#if BGL_PROFILE     BGLMPIO_T_CIO_SET_GET( 0, w, 0, 1, 0, BGLMPIO_CIO_LCOMP, BGLMPIO_CIO_LAST )#endif    /* only check for interleaving if cb_write isn't disabled */    if (fd->hints->cb_write != ADIOI_HINT_DISABLE) {	/* For this process's request, calculate the list of offsets and	   lengths in the file and determine the start and end offsets. */	/* Note: end_offset points to the last byte-offset that will be accessed.	   e.g., if start_offset=0 and 100 bytes to be read, end_offset=99*/	ADIOI_Calc_my_off_len(fd, count, datatype, file_ptr_type, offset,			      &offset_list, &len_list, &start_offset,			      &end_offset, &contig_access_count); #if BGL_PROFILE     BGLMPIO_T_CIO_SET_GET( 0, w, 1, 1, 1, BGLMPIO_CIO_GATHER, BGLMPIO_CIO_LCOMP )#endif	/* each process communicates its start and end offsets to other 	   processes. The result is an array each of start and end offsets stored	   in order of process rank. */     	st_offsets = (ADIO_Offset *) ADIOI_Malloc(nprocs*sizeof(ADIO_Offset));	end_offsets = (ADIO_Offset *) ADIOI_Malloc(nprocs*sizeof(ADIO_Offset));    if (bglmpio_tunegather) {            bgl_offsets0 = (ADIO_Offset *) ADIOI_Malloc(2*nprocs*sizeof(ADIO_Offset));            bgl_offsets  = (ADIO_Offset *) ADIOI_Malloc(2*nprocs*sizeof(ADIO_Offset));            for (ii=0; ii<nprocs; ii++)  {                bgl_offsets0[ii*2]   = 0;                bgl_offsets0[ii*2+1] = 0;            }            bgl_offsets0[myrank*2]   = start_offset;            bgl_offsets0[myrank*2+1] =   end_offset;        MPI_Allreduce( bgl_offsets0, bgl_offsets, nprocs*2, ADIO_OFFSET, MPI_MAX, fd->comm );            for (ii=0; ii<nprocs; ii++)  {                st_offsets [ii] = bgl_offsets[ii*2]  ;                end_offsets[ii] = bgl_offsets[ii*2+1];            }            ADIOI_Free( bgl_offsets0 );            ADIOI_Free( bgl_offsets  );    } else {	MPI_Allgather(&start_offset, 1, ADIO_OFFSET, st_offsets, 1,		      ADIO_OFFSET, fd->comm);	MPI_Allgather(&end_offset, 1, ADIO_OFFSET, end_offsets, 1,		      ADIO_OFFSET, fd->comm);    }#if BGL_PROFILE     BGLMPIO_T_CIO_SET_GET( 0, w, 0, 1, 1, BGLMPIO_CIO_PATANA, BGLMPIO_CIO_GATHER )#endif	/* are the accesses of different processes interleaved? */	for (i=1; i<nprocs; i++)      if ((st_offsets[i] < end_offsets[i-1]) &&          (st_offsets[i] <= end_offsets[i])) interleave_count++;                   	/* This is a rudimentary check for interleaving, but should suffice	   for the moment. */    }    ADIOI_Datatype_iscontig(datatype, &buftype_is_contig);    if (fd->hints->cb_write == ADIOI_HINT_DISABLE ||	(!interleave_count && (fd->hints->cb_write == ADIOI_HINT_AUTO)))    {	/* use independent accesses */	if (fd->hints->cb_write != ADIOI_HINT_DISABLE) {	    ADIOI_Free(offset_list);	    ADIOI_Free(len_list);	    ADIOI_Free(st_offsets);	    ADIOI_Free(end_offsets);	}	fd->fp_ind = orig_fp;        ADIOI_Datatype_iscontig(fd->filetype, &filetype_is_contig);        if (buftype_is_contig && filetype_is_contig) {            if (file_ptr_type == ADIO_EXPLICIT_OFFSET) {                off = fd->disp + (fd->etype_size) * offset;                ADIO_WriteContig(fd, buf, count, datatype,				 ADIO_EXPLICIT_OFFSET,				 off, status, error_code);            }            else ADIO_WriteContig(fd, buf, count, datatype, ADIO_INDIVIDUAL,				  0, status, error_code);        }	else ADIO_WriteStrided(fd, buf, count, datatype, file_ptr_type,			       offset, status, error_code);	return;    }#if BGL_PROFILE     BGLMPIO_T_CIO_SET_GET( 0, w, 1, 1, 1, BGLMPIO_CIO_FD_PART, BGLMPIO_CIO_PATANA )#endif	/* Divide the I/O workload among "nprocs_for_coll" processes. This is   done by (logically) dividing the file into file domains (FDs); each   process may directly access only its own file domain. */    if (bglmpio_tuneblocking)    ADIOI_BGL_GPFS_Calc_file_domains(st_offsets, end_offsets, nprocs,			    nprocs_for_coll, &min_st_offset,			    &fd_start, &fd_end, &fd_size, fd->fs_ptr);       else    ADIOI_Calc_file_domains(st_offsets, end_offsets, nprocs,			    nprocs_for_coll, &min_st_offset,			    &fd_start, &fd_end, &fd_size);   #if BGL_PROFILE     BGLMPIO_T_CIO_SET_GET( 0, w, 0, 1, 1, BGLMPIO_CIO_MYREQ, BGLMPIO_CIO_FD_PART )#endif	/* calculate what portions of the access requests of this process are   located in what file domains */    if (bglmpio_tuneblocking)    ADIOI_BGL_Calc_my_req(fd, offset_list, len_list, contig_access_count,		      min_st_offset, fd_start, fd_end, fd_size,		      nprocs, &count_my_req_procs, 		      &count_my_req_per_proc, &my_req,		      &buf_idx);     else    ADIOI_Calc_my_req(fd, offset_list, len_list, contig_access_count,		      min_st_offset, fd_start, fd_end, fd_size,		      nprocs, &count_my_req_procs, 		      &count_my_req_per_proc, &my_req,		      &buf_idx); #if BGL_PROFILE     BGLMPIO_T_CIO_SET_GET( 0, w, 1, 1, 1, BGLMPIO_CIO_OTHREQ, BGLMPIO_CIO_MYREQ )#endif	/* based on everyone's my_req, calculate what requests of other   processes lie in this process's file domain.   count_others_req_procs = number of processes whose requests lie in   this process's file domain (including this process itself)    count_others_req_per_proc[i] indicates how many separate contiguous   requests of proc. i lie in this process's file domain. */    if (bglmpio_tuneblocking)	ADIOI_BGL_Calc_others_req(fd, count_my_req_procs,			      count_my_req_per_proc, my_req,			      nprocs, myrank,			      &count_others_req_procs, &others_req);    else    ADIOI_Calc_others_req(fd, count_my_req_procs, 			  count_my_req_per_proc, my_req, 			  nprocs, myrank,			  &count_others_req_procs, &others_req);     #if BGL_PROFILE     BGLMPIO_T_CIO_SET_GET( 0, w, 1, 1, 1, BGLMPIO_CIO_DEXCH, BGLMPIO_CIO_OTHREQ )#endif    ADIOI_Free(count_my_req_per_proc);    for (i=0; i < nprocs; i++) {	if (my_req[i].count) {	    ADIOI_Free(my_req[i].offsets);	    ADIOI_Free(my_req[i].lens);	}    }    ADIOI_Free(my_req);/* exchange data and write in sizes of no more than coll_bufsize. */    ADIOI_Exch_and_write(fd, buf, datatype, nprocs, myrank,                        others_req, offset_list,			len_list, contig_access_count, min_st_offset,			fd_size, fd_start, fd_end, buf_idx, error_code);#if BGL_PROFILE     BGLMPIO_T_CIO_SET_GET( 0, w, 1, 0, 1, BGLMPIO_CIO_LAST, BGLMPIO_CIO_T_DEXCH )    BGLMPIO_T_CIO_SET_GET( 0, w, 0, 0, 1, BGLMPIO_CIO_LAST, BGLMPIO_CIO_T_MPIO_CRW )    BGLMPIO_T_CIO_REPORT( 0, w, fd, myrank )#endif	/* free all memory allocated for collective I/O */    for (i=0; i<nprocs; i++) {	if (others_req[i].count) {	    ADIOI_Free(others_req[i].offsets);	    ADIOI_Free(others_req[i].lens);	    ADIOI_Free(others_req[i].mem_ptrs);	}    }    ADIOI_Free(others_req);    ADIOI_Free(buf_idx);    ADIOI_Free(offset_list);    ADIOI_Free(len_list);    ADIOI_Free(st_offsets);    ADIOI_Free(end_offsets);    ADIOI_Free(fd_start);    ADIOI_Free(fd_end);#ifdef HAVE_STATUS_SET_BYTES    if (status) {      int bufsize, size;      /* Don't set status if it isn't needed */      MPI_Type_size(datatype, &size);      bufsize = size * count;      MPIR_Status_set_bytes(status, datatype, bufsize);    }/* This is a temporary way of filling in status. The right way is to    keep track of how much data was actually written during collective I/O. */#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -