#include "slavecommunication.h" #include "gadget.h" SlaveCommunication::SlaveCommunication() { MAXWAIT = 30; pvmConst = new PVMConstants(); typeReceived = -1; parenttid = -1; mytid = -1; myID = -1; numVar = 0; netDataVar = NULL; tmout.tv_sec = MAXWAIT; tmout.tv_usec = 0; } SlaveCommunication::~SlaveCommunication() { delete pvmConst; if (netDataVar != NULL) { delete netDataVar; netDataVar = NULL; } } void SlaveCommunication::printErrorMsg(const char* errorMsg) { /* Laga þetta þegar ég fer að pæla í error handler... */ char* msg; msg = new char[strlen(errorMsg) + 1]; strcpy(msg, errorMsg); //Prófum þetta hér, var notað pvm_perror sem skrifar villuna sem síðasta pvm kallið olli. std::cout << msg << "\n"; cerr << msg; delete[] msg; } int SlaveCommunication::startNetCommunication() { /* Þetta fall er komið í bili! */ int info, bytes, type, source; int OK = 1; int bufID = 0; //enroll in pvm and get identity of process for myself MPI_Init(NULL,NULL); MPI_Comm parentcomm; MPI_Status status; MPI_Comm_get_parent(&parentcomm); if (parentcomm == MPI_COMM_NULL) { printErrorMsg("Error in slavecommunication - process has not been spawned"); return 0; } int flag; // Þetta þarf að vera gert með timeout, prófum venjulegt blocking probe: //MPI_Iprobe(0, MPI_ANY_TAG, parentcomm, &flag,&status); MPI_Probe(0, MPI_ANY_TAG, parentcomm,&status); //if(flag == true) //{ if (status.MPI_TAG == pvmConst->getStopTag()) { int stopMessage; MPI_Recv(&stopMessage, 1, MPI_INT, 0, MPI_ANY_TAG, parentcomm, &status); typeReceived = pvmConst->getStopTag(); return !OK; } else if (status.MPI_TAG == pvmConst->getStartTag()) { MPI_Recv(&numVar, 1, MPI_INT, 0, MPI_ANY_TAG, parentcomm, &status); if (numVar <= 0) { cerr << "Error in slavecommunication - number of variables received from master is less than zero\n"; return !OK; } MPI_Recv(&myID, 1, MPI_INT, 0, MPI_ANY_TAG, parentcomm, &status); if (myID < 0) { cerr << "Error in slavecommunication - received invalid id of " << myID << endl; return !OK; } netDataVar = new NetDataVariables(numVar); typeReceived = pvmConst->getStartTag(); return numVar; } else { cerr << "Error in slavecommunication - received unrecognised tag of type " << status.MPI_TAG << endl; return !OK; } //} //else //{ // cerr << "Error in slavecommunication - non-blocking-probe fail" << endl; // return !OK; //} } void SlaveCommunication::stopNetCommunication() { MPI_Finalize(); } int SlaveCommunication::sendToMaster(double res) { int info; assert(netDataVar != NULL); if (netDataVar->x_id < 0 || netDataVar->tag < 0) { printErrorMsg("Error in slavecommunication - invalid id received\n"); return 0; } else if (myID < 0) { printErrorMsg("Error in slavecommunication - invalid id received\n"); return 0; } else { //cout << "Slave að skrifa result: " << res << "\n"; NetDataResult* sendData = new NetDataResult; sendData->who = myID; sendData->result = res; sendData->x_id = netDataVar->x_id; sendData->tag = netDataVar->tag; info = send(sendData); delete sendData; if (info > 0) { netDataVar->tag = -1; netDataVar->x_id = -1; return 1; } else return 0; } return 0; } int SlaveCommunication::send(NetDataResult* sendData) { int info; MPI_Comm parentcomm; //cout << "Slave að skrifa result: " << sendData->result << "\n"; MPI_Comm_get_parent(&parentcomm); MPI_Send(&sendData->tag,1,MPI_INT, 0, pvmConst->getMasterReceiveDataTag(),parentcomm); MPI_Send(&sendData->result,1,MPI_DOUBLE, 0, pvmConst->getMasterReceiveDataTag(),parentcomm); MPI_Send(&sendData->who,1,MPI_INT, 0, pvmConst->getMasterReceiveDataTag(),parentcomm); MPI_Send(&sendData->x_id,1,MPI_INT, 0, pvmConst->getMasterReceiveDataTag(),parentcomm); return 1; } int SlaveCommunication::receiveFromMaster() { /* Þetta fall er komið í bili, þarf samt að skoða með þetta TIMEOUT fall... */ int bufID = 0; int OK = 1; int info, bytes, source, type; typeReceived = -1; MPI_Status status; MPI_Comm parentcomm; MPI_Comm_get_parent(&parentcomm); // Hér er hægt að nota non-blocking probe til að komast eitthvað til móts við þetta timeout, hægt // að láta það bíða í einhvern tíma og probe-a aftur... Hérna gæti verið góð pæling að útfæra bara // sjálfur Timout fall sem testar á fullu í Maxwait tíma og skilar ef flag er true... Ætla að breyta // þessu í bili, en ræð við Bjarka upp á framhaldið... // Update: Þetta virkar svona, svo það er e.t.v. ekki nein ástæða til að breyta þessu. MPI_Probe(0, MPI_ANY_TAG, parentcomm, &status); //bufID = pvm_trecv(parenttid, -1, &tmout); if (status.MPI_TAG == pvmConst->getStopTag()) { //receive information from master to quit int stopMessage; MPI_Recv(&stopMessage, 1, MPI_INT, 0, MPI_ANY_TAG, parentcomm, &status); typeReceived = pvmConst->getStopTag(); return !OK; } else if (status.MPI_TAG == pvmConst->getMasterSendStringTag()) { // There is an incoming message of data type stringDataVariables info = receiveString(); typeReceived = pvmConst->getMasterSendStringTag(); if (info > 0) return 1; return 0; } else if (status.MPI_TAG == pvmConst->getMasterSendBoundTag()) { // There is an incoming message of data type double for the bounds info = receiveBound(); typeReceived = pvmConst->getMasterSendBoundTag(); if (info > 0) return 1; return 0; } else if (status.MPI_TAG == pvmConst->getMasterSendVarTag()) { //There is an incoming message of data type NetDataVariables info = receive(); if (info > 0) { typeReceived = pvmConst->getMasterSendVarTag(); return 1; } return 0; } else { cerr << "Error in slavecommunication - received unrecognised tag of type " << type << endl; return !OK; } } int SlaveCommunication::receiveBound() { int i; double* temp = new double[numVar]; MPI_Status status; MPI_Comm parentcomm; MPI_Comm_get_parent(&parentcomm); MPI_Recv(temp,numVar,MPI_DOUBLE,0,MPI_ANY_TAG,parentcomm,&status); netDataDouble.Reset(); netDataDouble.resize(numVar, 0.0); for (i = 0; i < numVar; i++) { netDataDouble[i] = temp[i]; } delete [] temp; return 1; } int SlaveCommunication::receive() { int info, i; MPI_Status status; MPI_Comm parentcomm; MPI_Comm_get_parent(&parentcomm); MPI_Recv(&netDataVar->tag,1,MPI_INT, 0,MPI_ANY_TAG, parentcomm,&status); MPI_Recv(&netDataVar->x_id, 1, MPI_INT, 0,MPI_ANY_TAG, parentcomm, &status); MPI_Recv(netDataVar->x, numVar,MPI_DOUBLE,0,MPI_ANY_TAG, parentcomm, &status); return 1; } int SlaveCommunication::receivedVector() { if (pvmConst->getMasterSendVarTag() == typeReceived) return 1; return 0; } // Þetta var ekki að virka rétt þar sem kallað var á þetta í Gadget. //void SlaveCommunication::getVector(DoubleVector& vec) //{ // /* // Senda út villu ef þetta if condition er ekki uppfyllt... G.E. // */ // int i; // if (vec.Size() != numVar) // { // // error.... // } // // for (i = 0; i < numVar; i++) // vec[i] = netDataVar->x[i]; //} void SlaveCommunication::getVector(double* vec) { int i; for (i = 0; i < numVar; i++) vec[i] = netDataVar->x[i]; } int SlaveCommunication::getReceiveType() { return typeReceived; } int SlaveCommunication::receiveString() { int OK = 1; int i, info; char* tempString = new char[MaxStrLength + 1]; strncpy(tempString, "", MaxStrLength); tempString[MaxStrLength] = '\0'; MPI_Status status; MPI_Comm parentcomm; MPI_Comm_get_parent(&parentcomm); for (i = 0; i < numVar; i++) { strncpy(tempString, "\0", MaxStrLength+1); MPI_Recv(tempString, MaxStrLength, MPI_BYTE, 0,MPI_ANY_TAG, parentcomm, &status); Parameter pm(tempString); netDataStr.resize(pm); } delete [] tempString; return OK; } int SlaveCommunication::receivedString() { if (pvmConst->getMasterSendStringTag() == typeReceived) return 1; return 0; } int SlaveCommunication::receivedBounds() { if (pvmConst->getMasterSendBoundTag() == typeReceived) return 1; return 0; } const ParameterVector& SlaveCommunication::getStringVector() { return netDataStr; } const Parameter& SlaveCommunication::getString(int num) { assert(num >= 0); assert(netDataStr.Size() == numVar); return netDataStr[num]; } // Þetta var ekki að virka rétt þar sem kallað var á þetta í Gadget. //void SlaveCommunication::getBound(DoubleVector& vec) //{ // int i; // if (vec.Size() != numVar) // // errror... // /* // for (i = 0; i < numVar; i++) // vec[i] = netDataDouble[i]; // */ // vec = netDataDouble; //} void SlaveCommunication::getBound(double* vec) { int i; for (i = 0; i < numVar; i++) vec[i] = netDataDouble[i]; }