/* * Copyright (C) 2011 Thorsten Liebig (Thorsten.Liebig@gmx.de) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY{} without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "engine_mpi.h" Engine_MPI* Engine_MPI::New(const Operator_MPI* op) { cout << "Create FDTD engine (compressed SSE + MPI)" << endl; Engine_MPI* e = new Engine_MPI(op); e->Init(); return e; } Engine_MPI::Engine_MPI(const Operator_MPI* op) : Engine_SSE_Compressed(op) { m_Op_MPI = op; } Engine_MPI::~Engine_MPI() { Reset(); } void Engine_MPI::Init() { Engine_SSE_Compressed::Init(); for (int i=0;i<3;++i) { m_BufferUp[i]=NULL; m_BufferDown[i]=NULL; m_BufferSize[i]=0; } if (m_Op_MPI->GetMPIEnabled()) { // init buffers, nx*ny*2 for the tangential electric or magnetic fields at the interface for (int n=0;n<3;++n) { int nP = (n+1)%3; int nPP = (n+2)%3; m_BufferSize[n] = m_Op_MPI->numLines[nP]*m_Op_MPI->numLines[nPP]; if (m_Op_MPI->m_NeighborDown[n]>=0) { m_BufferDown[n] = new float[m_BufferSize[n]*3]; } if (m_Op_MPI->m_NeighborUp[n]>=0) { m_BufferUp[n] = new float[m_BufferSize[n]*3]; } } } } void Engine_MPI::Reset() { for (int i=0;i<3;++i) { delete[] m_BufferUp[i]; delete[] m_BufferDown[i]; m_BufferUp[i]=NULL; m_BufferDown[i]=NULL; m_BufferSize[i]=0; } Engine_SSE_Compressed::Reset(); } void Engine_MPI::SendReceiveVoltages() { if (!m_Op_MPI->GetMPIEnabled()) return; unsigned int pos[3]; //non-blocking prepare for receive... for (int n=0;n<3;++n) if (m_Op_MPI->m_NeighborDown[n]>=0) MPI_Irecv( m_BufferDown[n] , m_BufferSize[n]*2, MPI_FLOAT, m_Op_MPI->m_NeighborDown[n], m_Op_MPI->m_MyTag, MPI_COMM_WORLD, &Recv_Request[n]); for (int n=0;n<3;++n) { int nP = (n+1)%3; int nPP = (n+2)%3; //send voltages unsigned int iPos=0; pos[n]=numLines[n]-1; if (m_Op_MPI->m_NeighborUp[n]>=0) { for (pos[nP]=0; pos[nP]m_NeighborUp[n], m_Op_MPI->m_MyTag, MPI_COMM_WORLD, &Send_Request[n]); } //receive voltages pos[n]=0; iPos=0; if (m_Op_MPI->m_NeighborDown[n]>=0) { //wait for receive to finish... MPI_Wait(&Recv_Request[n],&stat); for (pos[nP]=0; pos[nP]GetMPIEnabled()) return; unsigned int pos[3]; //non-blocking prepare for receive... for (int n=0;n<3;++n) if (m_Op_MPI->m_NeighborUp[n]>=0) MPI_Irecv( m_BufferUp[n] , m_BufferSize[n]*3, MPI_FLOAT, m_Op_MPI->m_NeighborUp[n], m_Op_MPI->m_MyTag, MPI_COMM_WORLD, &Recv_Request[n]); for (int n=0;n<3;++n) { int nP = (n+1)%3; int nPP = (n+2)%3; //send currents unsigned int iPos=0; pos[n]=0; if (m_Op_MPI->m_NeighborDown[n]>=0) { for (pos[nP]=0; pos[nP]m_NeighborDown[n], m_Op_MPI->m_MyTag, MPI_COMM_WORLD, &Send_Request[n]); } //receive currents pos[n]=numLines[n]-1; iPos=0; if (m_Op_MPI->m_NeighborUp[n]>=0) { //wait for receive to finish... MPI_Wait(&Recv_Request[n],&stat); for (pos[nP]=0; pos[nP]GetMPIEnabled()) { return Engine_SSE_Compressed::IterateTS(iterTS); } for (unsigned int iter=0; iter