/***************************************************************************** * CVS File Information : * $RCSfile$ * Author: patmiller $ * Date: 2007/06/11 14:12:54 $ * Revision: 1.3 $ ****************************************************************************/ /***********************************************************************************************/ /* FILE ************************** _MPI_SENDREC_UTIL.c *********************************/ /***********************************************************************************************/ /* Author : Lisa Alano June 26 2002 */ /* Copyright (c) 2002 University of California Regents */ /***********************************************************************************************/ #include #include #include #include "mpi.h" /*=============================================================================================*/ int _MPI_checks (void *message, int count, MPI_Datatype data, int dest, int tag, MPI_Comm comm) { int buf,cnt,dat,des,tad,com; _MPI_COVERAGE(); buf=_MPI_checkBuffer(message); cnt=_MPI_checkCount(count); dat=_MPI_checkDatatype(data); des=_MPI_checkDestination(dest); tad=_MPI_checkTag(tag); com=_MPI_checkCommunicator(comm); if (buf == MPI_SUCCESS) { if (cnt == MPI_SUCCESS) { if (dat == MPI_SUCCESS) { if (des == MPI_SUCCESS) { if (tad == MPI_SUCCESS) { if (com == MPI_SUCCESS) { return (int)MPI_SUCCESS; } return MPI_ERR_COMM; } return MPI_ERR_TAG; } return MPI_ERR_RANK; } return MPI_ERR_TYPE; } return MPI_ERR_COUNT; } return MPI_ERR_BUFFER; } /*=============================================================================================*/ int _MPI_checkBuffer(void* message) { if(message == (void *)NULL) return _MPI_NOT_OK; return MPI_SUCCESS; } /*=============================================================================================*/ int _MPI_checkCount(int count) { if(count >= 0) return MPI_SUCCESS; return MPI_ERR_COUNT; } /*=============================================================================================*/ int _MPI_checkDatatype(MPI_Datatype type) { if ( (type>=_MPI_TYPE_START) && (type<=_MPI_TYPE_END+_MPI_TYPE_COUNT) ) return MPI_SUCCESS; return MPI_ERR_TYPE; } /*=============================================================================================*/ int _MPI_checkDestination(int dest) { if ( (dest==_MPI_RANK)||dest==(MPI_ANY_SOURCE) ) return MPI_SUCCESS; return MPI_ERR_RANK; } /*=============================================================================================*/ int _MPI_checkTag(int tag) { if ( (tag == MPI_ANY_TAG) || (tag>=0) ) return MPI_SUCCESS; return MPI_ERR_TAG; } /*=============================================================================================*/ int _MPI_checkCommunicator(MPI_Comm comm) { int index; return _MPI_Comm_check_legal(comm, &index); } /*=============================================================================================*/ int _MPI_calculateSize(int count, MPI_Datatype type) { int size; if (count == 0) return 0; size = _MPI_getSize(type); return size*count; } /*=============================================================================================*/ /* EDIT for other types ========================= */ /* Not included: MPI_PACKED and FORTRAN DATATYPES */ /* ============================================== */ int _MPI_getSize(MPI_Datatype type) { switch(type) { case MPI_CHAR: return sizeof(char); case MPI_BYTE: return sizeof(char); case MPI_SHORT: return sizeof(short); case MPI_INT: return sizeof(int); case MPI_LONG: return sizeof(long); case MPI_LONG_LONG: /* KDD Added 11/19/15 */ return sizeof(long long); case MPI_FLOAT: return sizeof(float); case MPI_DOUBLE: return sizeof(double); case MPI_UNSIGNED_CHAR: return sizeof(unsigned char); case MPI_UNSIGNED_SHORT: return sizeof(unsigned short); case MPI_UNSIGNED: return sizeof(unsigned); case MPI_UNSIGNED_LONG: return sizeof(unsigned long); case MPI_LONG_DOUBLE: return sizeof(long double); case MPI_UB: return sizeof(MPI_Aint); case MPI_LB: return sizeof(MPI_Aint); case MPI_FLOAT_INT: return sizeof(_MPI_FLOAT_INT); case MPI_LONG_INT: return sizeof(_MPI_LONG_INT); case MPI_DOUBLE_INT: return sizeof(_MPI_DOUBLE_INT); case MPI_2INT: return sizeof(_MPI_2INT); case MPI_LONG_DOUBLE_INT: return sizeof(_MPI_LONG_DOUBLE_INT); case MPI_LONG_LONG_INT: return sizeof(_MPI_LONG_LONG_INT); default: return _MPI_calculateStructureSize(type); } } /*=============================================================================================*/ int _MPI_calculateStructureSize (MPI_Datatype type) { int index, size; _MPI_TYPE_DES* datatype; index = _MPI_FindType(type); if (index == _MPI_NOT_OK) { _MPI_ERR_ROUTINE (MPI_ERR_TYPE, "MPI: Datatype error. No such datatype exists."); MPI_Abort (MPI_COMM_NULL, MPI_ERR_TYPE); } datatype = &_MPI_TYPE_LIST[index]; /* KDD 6/2/16 Comment below says this return value should be extent, KDD 6/2/16 not size. I agree. size = datatype->size; */ /*EDIT should be extent */ size = datatype->extent; return size; } /*=============================================================================================*/ int _MPI_checkRequest (MPI_Request request) { if (request == MPI_REQUEST_NULL) return MPI_ERR_REQUEST; return MPI_SUCCESS; } /*=============================================================================================*/ /* Same as _MPI_Buff_Insert below. */ /* This is for Buffered Send or Bsend - where you use the user's buffer*/ int _MPI_Bbuff_Insert(void *message,int count,MPI_Datatype datatype,int tag,MPI_Comm comm) { int index; for (index=0; index < _MPI_DATA_ARRAY_SIZE ; index++) { if (_MPI_DATA_BUFF[index].valid == _MPI_NOT_VALID) { _MPI_DATA_BUFF[index].valid = _MPI_VALID; _MPI_DATA_BUFF[index].buffer = message; _MPI_DATA_BUFF[index].count = count; _MPI_DATA_BUFF[index].type = datatype; _MPI_DATA_BUFF[index].tag = tag; _MPI_DATA_BUFF[index].comm = comm; /* ----------------------------------- */ _MPI_DATA_BUFF[index].user = _MPI_TRUE; /* this is where the DIFFERENCE occurs */ _MPI_DATA_BUFF_COUNT++; return MPI_SUCCESS; } } /* ----------------------------------------------- */ /* This realloc is OK because internal references */ /* to the list never escape. We just search the */ /* whole list for matches. */ /* ----------------------------------------------- */ _MPI_DATA_BUFF = (_MPI_DATA_ENTRY*) _MPI_safeRealloc (_MPI_DATA_BUFF, (_MPI_DATA_ARRAY_SIZE+_MPI_PREALLOCATION_SIZE)*sizeof(_MPI_DATA_ENTRY), "Error in _MPI_Buff_Insert for reallocation"); _MPI_DATA_ARRAY_SIZE+=_MPI_PREALLOCATION_SIZE; _MPI_DATA_BUFF[index].valid = _MPI_VALID; _MPI_DATA_BUFF[index].buffer = message; _MPI_DATA_BUFF[index].count = count; _MPI_DATA_BUFF[index].type = datatype; _MPI_DATA_BUFF[index].tag = tag; _MPI_DATA_BUFF[index].comm = comm; _MPI_DATA_BUFF[index].user = _MPI_TRUE; _MPI_DATA_BUFF_COUNT++; return MPI_SUCCESS; } /*=============================================================================================*/ /* Same as _MPI_Bbuff_Insert above. */ int _MPI_Buff_Insert(void *message,int count,MPI_Datatype datatype,int tag,MPI_Comm comm) { int index; for (index=0; index < _MPI_DATA_ARRAY_SIZE ; index++) { if (_MPI_DATA_BUFF[index].valid == _MPI_NOT_VALID) { _MPI_DATA_BUFF[index].valid = _MPI_VALID; _MPI_DATA_BUFF[index].buffer = message; _MPI_DATA_BUFF[index].count = count; _MPI_DATA_BUFF[index].type = datatype; _MPI_DATA_BUFF[index].tag = tag; _MPI_DATA_BUFF[index].comm = comm; _MPI_DATA_BUFF[index].user = _MPI_FALSE; _MPI_DATA_BUFF_COUNT++; return MPI_SUCCESS; } } _MPI_DATA_BUFF = (_MPI_DATA_ENTRY*) _MPI_safeRealloc (_MPI_DATA_BUFF, (_MPI_DATA_ARRAY_SIZE+_MPI_PREALLOCATION_SIZE)*sizeof(_MPI_DATA_ENTRY), "Error in _MPI_Buff_Insert for reallocation"); _MPI_DATA_ARRAY_SIZE+=_MPI_PREALLOCATION_SIZE; _MPI_DATA_BUFF[index].valid = _MPI_VALID; _MPI_DATA_BUFF[index].buffer = message; _MPI_DATA_BUFF[index].count = count; _MPI_DATA_BUFF[index].type = datatype; _MPI_DATA_BUFF[index].tag = tag; _MPI_DATA_BUFF[index].comm = comm; _MPI_DATA_BUFF[index].user = _MPI_FALSE; _MPI_DATA_BUFF_COUNT++; return MPI_SUCCESS; } /*=============================================================================================*/ int _MPI_Data_Invalid(int index) { if ( (index>=0)&&(index<_MPI_DATA_ARRAY_SIZE) ) { if(_MPI_DATA_BUFF[index].user==_MPI_TRUE) { ; } else { _MPI_safeFree(_MPI_DATA_BUFF[index].buffer,"BUFF buffer"); _MPI_DATA_BUFF[index].buffer = 0; } _MPI_DATA_BUFF[index].valid = _MPI_NOT_VALID; _MPI_DATA_BUFF[index].buffer = (void *) NULL; _MPI_DATA_BUFF[index].count = _MPI_NOT_VALID; _MPI_DATA_BUFF[index].type = _MPI_NOT_VALID; _MPI_DATA_BUFF[index].tag = _MPI_NOT_VALID; _MPI_DATA_BUFF[index].comm = MPI_COMM_NULL; _MPI_DATA_BUFF[index].user = _MPI_NOT_VALID; return MPI_SUCCESS; } return _MPI_NOT_OK; } /*=============================================================================================*/ int _MPI_Type_Invalid(int index) { if ( (index>=0)&&(index<_MPI_TYPE_ARRAY_SIZE) ) { _MPI_TYPE_LIST[index].id = _MPI_NOT_VALID; _MPI_TYPE_LIST[index].extent = 0; _MPI_TYPE_LIST[index].next = (_MPI_TYPE_DES *) NULL; return MPI_SUCCESS; } return _MPI_NOT_OK; } /*=============================================================================================*/ int _MPI_Buff_Ifind(int tag, MPI_Comm comm) { int index; for (index=0; index<_MPI_DATA_BUFF_COUNT; index++) { if(_MPI_DATA_BUFF[index].valid == _MPI_VALID) { if (_MPI_DATA_BUFF[index].comm == comm) { if ( (_MPI_DATA_BUFF[index].tag == tag)||(tag == MPI_ANY_TAG) ) { return index; } } } } return _MPI_NOT_OK; } /**************************************************************************/ /* GLOBAL ************** _MPI_Buff_Find ************************/ /**************************************************************************/ /* Match the tag to a current message */ /**************************************************************************/ int _MPI_Buff_Find(int tag, MPI_Comm comm) { int index; for (index=0; index<_MPI_DATA_BUFF_COUNT; index++) { if(_MPI_DATA_BUFF[index].valid == _MPI_VALID) { if (_MPI_DATA_BUFF[index].comm == comm) { if ( (_MPI_DATA_BUFF[index].tag == tag)||(tag == MPI_ANY_TAG) ) { #ifdef _MPI_DEBUG ;/*printf("Found at index=%d\n",index);*/ #endif return index; } } } } return _MPI_NOT_OK; } /*==========================================================================*/