/*******************************************************************/ /* XDMF */ /* eXtensible Data Model and Format */ /* */ /* Id : Id */ /* Date : $Date$ */ /* Version : $Revision$ */ /* */ /* Author: */ /* Jerry A. Clarke */ /* clarke@arl.army.mil */ /* US Army Research Laboratory */ /* Aberdeen Proving Ground, MD */ /* */ /* Copyright @ 2007 US Army Research Laboratory */ /* All Rights Reserved */ /* See Copyright.txt or http://www.arl.hpc.mil/ice for details */ /* */ /* This software is distributed WITHOUT ANY WARRANTY; without */ /* even the implied warranty of MERCHANTABILITY or FITNESS */ /* FOR A PARTICULAR PURPOSE. See the above copyright notice */ /* for more information. */ /* */ /*******************************************************************/ #include "XdmfDsm.h" #include "XdmfDsmComm.h" #include "XdmfDsmMsg.h" #include "XdmfArray.h" namespace xdmf2 { // Align typedef struct { XdmfInt64 Opcode; XdmfInt64 Source; XdmfInt64 Target; XdmfInt64 Address; XdmfInt64 Length; XdmfInt64 Parameters[10]; } XdmfDsmCommand; XdmfDsm::XdmfDsm() { this->DsmType = XDMF_DSM_TYPE_UNIFORM; this->Storage = new XdmfArray; this->StorageIsMine = 1; this->Locks = 0; // For Alignment this->Storage->SetNumberType(XDMF_INT64_TYPE); this->SetLength(XDMF_DSM_DEFAULT_LENGTH); this->DataPointer = (XdmfByte *)this->Storage->GetDataPointer(); this->StartAddress = 0; this->EndAddress = this->StartAddress + this->Length - 1; this->Comm = 0; this->StartServerId = this->EndServerId = -1; this->Msg = new XdmfDsmMsg; } XdmfDsm::~XdmfDsm() { if(this->Storage && this->StorageIsMine) delete this->Storage; if(this->Msg) delete this->Msg; } XdmfInt32 XdmfDsm::Copy(XdmfDsm *Source){ this->DsmType = Source->DsmType; if (this->Storage) delete this->Storage; this->Storage = Source->GetStorage(); this->StorageIsMine = 0; this->DataPointer = (XdmfByte *)this->Storage->GetDataPointer(); // For Alignment this->Length = Source->Length; this->StartAddress = Source->StartAddress; this->EndAddress = Source->EndAddress; this->Comm = Source->Comm; this->StartServerId = Source->StartServerId; this->EndServerId = Source->EndServerId; this->Locks = Source->Locks; // Always make a new Message so there is no contention if (this->Msg) delete this->Msg; this->Msg = new XdmfDsmMsg; return(XDMF_SUCCESS); } XdmfInt32 XdmfDsm::SetStorage(XdmfArray *aStorage){ if(this->Storage && this->StorageIsMine) delete this->Storage; this->Storage = aStorage; this->DataPointer = (XdmfByte *)this->Storage->GetDataPointer(); return(XDMF_SUCCESS); } XdmfInt32 XdmfDsm::ConfigureUniform(XdmfDsmComm *aComm, XdmfInt64 aLength, XdmfInt32 StartId, XdmfInt32 EndId){ if(StartId < 0) StartId = 0; if(EndId < 0) EndId = aComm->GetTotalSize() - 1; this->SetDsmType(XDMF_DSM_TYPE_UNIFORM_RANGE); if((StartId == 0) && (EndId == aComm->GetTotalSize() - 1)){ this->SetDsmType(XDMF_DSM_TYPE_UNIFORM); } this->SetStartServerId(StartId); this->SetEndServerId(EndId); this->SetComm(aComm); if((aComm->GetId() >= StartId) && (aComm->GetId() <= EndId)){ this->SetLength(aLength); this->StartAddress = (aComm->GetId() - StartId) * aLength; this->EndAddress = this->StartAddress + aLength - 1; }else{ this->Length = aLength; } this->Msg->Source = this->Comm->GetId(); this->TotalLength = aLength * (EndId - StartId + 1); return(XDMF_SUCCESS); } XdmfInt32 XdmfDsm::GetAddressRangeForId(XdmfInt32 Id, XdmfInt64 *Start, XdmfInt64 *End){ switch(this->DsmType) { case XDMF_DSM_TYPE_UNIFORM : case XDMF_DSM_TYPE_UNIFORM_RANGE : // All Servers have same length *Start = (Id - this->StartServerId) * this->Length; *End = *Start + Length - 1; break; default : // Not Implemented XdmfErrorMessage("DsmType " << this->DsmType << " not yet implemented"); return(XDMF_FAIL); break; } return(XDMF_SUCCESS); } XdmfInt32 XdmfDsm::AddressToId(XdmfInt64 Address){ XdmfInt32 ServerId = XDMF_FAIL; switch(this->DsmType) { case XDMF_DSM_TYPE_UNIFORM : case XDMF_DSM_TYPE_UNIFORM_RANGE : // All Servers have same length ServerId = this->StartServerId + (Address / this->Length); if(ServerId > this->EndServerId ){ XdmfErrorMessage("ServerId " << ServerId << " for Address " << Address << " is larger than EndServerId " << this->EndServerId); } break; default : // Not Implemented XdmfErrorMessage("DsmType " << this->DsmType << " not yet implemented"); break; } return(ServerId); } XdmfInt32 XdmfDsm::SendDone(){ XdmfInt32 who, status = XDMF_SUCCESS; switch(this->DsmType) { case XDMF_DSM_TYPE_UNIFORM : case XDMF_DSM_TYPE_UNIFORM_RANGE : for(who = this->StartServerId ; who <= this->EndServerId ; who++){ status = this->SendCommandHeader(XDMF_DSM_OPCODE_DONE, who, 0, 0); } break; default : // Not Implemented XdmfErrorMessage("DsmType " << this->DsmType << " not yet implemented"); break; } return(status); } XdmfInt32 XdmfDsm::SetLength(XdmfInt64 aLength){ // Make it longer than actually needed for round off. if(this->Storage->SetNumberOfElements((aLength / sizeof(XdmfInt64)) + 1) != XDMF_SUCCESS){ XdmfErrorMessage("Cannot set Dsm Length to " << Length); return(XDMF_FAIL); } this->Length = aLength; this->DataPointer = (XdmfByte *)this->Storage->GetDataPointer(); return(XDMF_SUCCESS); } XdmfInt32 XdmfDsm::SendCommandHeader(XdmfInt32 Opcode, XdmfInt32 Dest, XdmfInt64 Address, XdmfInt64 aLength){ XdmfDsmCommand Cmd; XdmfInt32 Status; Cmd.Opcode = Opcode; Cmd.Source = this->Comm->GetId(); Cmd.Target = Dest; Cmd.Address = Address; Cmd.Length = aLength; this->Msg->SetSource(this->Comm->GetId()); this->Msg->SetDest(Dest); this->Msg->SetTag(XDMF_DSM_COMMAND_TAG); this->Msg->SetLength(sizeof(Cmd)); this->Msg->SetData(&Cmd); Status = this->Comm->Send(this->Msg); XdmfDebug("(" << this->Comm->GetId() << ") sent opcode " << Cmd.Opcode); return(Status); } XdmfInt32 XdmfDsm::ReceiveCommandHeader(XdmfInt32 *Opcode, XdmfInt32 *Source, XdmfInt64 *Address, XdmfInt64 *aLength, XdmfInt32 Block){ XdmfDsmCommand Cmd; XdmfInt32 status = XDMF_FAIL; this->Msg->Source = XDMF_DSM_ANY_SOURCE; this->Msg->SetLength(sizeof(Cmd)); this->Msg->SetTag(XDMF_DSM_COMMAND_TAG); this->Msg->SetData(&Cmd); memset(&Cmd, 0, sizeof(XdmfDsmCommand)); status = this->Comm->Check(this->Msg); if((status != XDMF_FAIL) || Block){ status = this->Comm->Receive(this->Msg); if(status == XDMF_FAIL){ XdmfErrorMessage("Communicator Receive Failed"); return(XDMF_FAIL); }else{ *Opcode = Cmd.Opcode; *Source = Cmd.Source; *Address = Cmd.Address; *aLength = Cmd.Length; status = XDMF_SUCCESS; XdmfDebug("(Server " << this->Comm->GetId() << ") got opcode " << Cmd.Opcode); } } return(status); } XdmfInt32 XdmfDsm::SendData(XdmfInt32 Dest, void *Data, XdmfInt64 aLength){ this->Msg->SetSource(this->Comm->GetId()); this->Msg->SetDest(Dest); this->Msg->SetLength(aLength); // this->Msg->SetTag(XDMF_DSM_RESPONSE_TAG); this->Msg->SetData(Data); return(this->Comm->Send(this->Msg)); } XdmfInt32 XdmfDsm::ReceiveData(XdmfInt32 Source, void *Data, XdmfInt64 aLength, XdmfInt32 Block){ XdmfInt32 Status = XDMF_FAIL; this->Msg->SetSource(Source); this->Msg->SetLength(aLength); // this->Msg->SetTag(XDMF_DSM_RESPONSE_TAG); this->Msg->SetData(Data); if(Block){ Status = this->Comm->Receive(this->Msg); }else{ Status = this->Comm->Check(this->Msg); if(Status == XDMF_SUCCESS){ Status = this->Comm->Receive(this->Msg); } } return(Status); } }