/* * Copyright (C) 2010 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 "operator_sse_compressed.h" #include "engine_sse_compressed.h" #include "engine_sse.h" #include "tools/array_ops.h" #include #include Operator_SSE_Compressed* Operator_SSE_Compressed::New() { cout << "Create FDTD operator (compressed SSE)" << endl; Operator_SSE_Compressed* op = new Operator_SSE_Compressed(); op->Init(); return op; } Operator_SSE_Compressed::Operator_SSE_Compressed() : Operator_sse() { m_Op_index = NULL; m_Use_Compression = false; } Operator_SSE_Compressed::~Operator_SSE_Compressed() { Delete(); } Engine* Operator_SSE_Compressed::CreateEngine() const { if (!m_Use_Compression) { //! create a default sse-engine Engine_sse* eng = Engine_sse::New(this); return eng; } Engine_SSE_Compressed* eng = Engine_SSE_Compressed::New(this); return eng; } int Operator_SSE_Compressed::CalcECOperator( DebugFlags debugFlags ) { int ErrCode = Operator_sse::CalcECOperator( debugFlags ); m_Use_Compression = false; m_Use_Compression = CompressOperator(); return ErrCode; } void Operator_SSE_Compressed::Init() { Operator_sse::Init(); m_Use_Compression = false; m_Op_index = NULL; } void Operator_SSE_Compressed::Delete() { if (m_Op_index) { Delete3DArray( m_Op_index, numLines ); m_Op_index = 0; } m_Use_Compression = false; for (int n=0; n<3; n++) { f4_vv_Compressed[n].clear(); f4_vi_Compressed[n].clear(); f4_iv_Compressed[n].clear(); f4_ii_Compressed[n].clear(); } } void Operator_SSE_Compressed::Reset() { Delete(); Operator_sse::Reset(); } void Operator_SSE_Compressed::InitOperator() { //cleanup compression m_Use_Compression = false; for (int n=0; n<3; n++) { f4_vv_Compressed[n].clear(); f4_vi_Compressed[n].clear(); f4_iv_Compressed[n].clear(); f4_ii_Compressed[n].clear(); } Operator_sse::InitOperator(); m_Op_index = Create3DArray( numLines ); } void Operator_SSE_Compressed::ShowStat() const { Operator_sse::ShowStat(); cout << "SSE compression enabled\t: " << (m_Use_Compression?"yes":"no") << endl; cout << "Unique SSE operators\t: " << f4_vv_Compressed->size() << endl; cout << "-----------------------------------" << endl; } bool Operator_SSE_Compressed::CompressOperator() { if (g_settings.GetVerboseLevel()>0) cout << "Compressing the FDTD operator... this may take a while..." << endl; map lookUpMap; unsigned int pos[3]; for (pos[0]=0; pos[0]::iterator it; it = lookUpMap.find(c); if (it == lookUpMap.end()) { // not found -> insert unsigned int index = f4_vv_Compressed[0].size(); for (int n=0; n<3; n++) { f4_vv_Compressed[n].push_back( vv[n] ); f4_vi_Compressed[n].push_back( vi[n] ); f4_iv_Compressed[n].push_back( iv[n] ); f4_ii_Compressed[n].push_back( ii[n] ); } lookUpMap[c] = index; m_Op_index[pos[0]][pos[1]][pos[2]] = index; } else { // this operator is already in the list unsigned int index = (*it).second; m_Op_index[pos[0]][pos[1]][pos[2]] = index; } } } } Delete_N_3DArray_v4sf(f4_vv,numLines); Delete_N_3DArray_v4sf(f4_vi,numLines); Delete_N_3DArray_v4sf(f4_iv,numLines); Delete_N_3DArray_v4sf(f4_ii,numLines); f4_vv = 0; f4_vi = 0; f4_iv = 0; f4_ii = 0; return true; } // ---------------------------------------------------------------------------- SSE_coeff::SSE_coeff( f4vector vv[3], f4vector vi[3], f4vector iv[3], f4vector ii[3] ) { for (int n=0; n<3; n++) { m_vv[n] = vv[n]; m_vi[n] = vi[n]; m_iv[n] = iv[n]; m_ii[n] = ii[n]; } } bool SSE_coeff::operator==( const SSE_coeff& other ) const { for (int n=0; n<3; n++) { if (memcmp( &(m_vv[n]), &(other.m_vv[n]), sizeof(f4vector) ) != 0) return false; if (memcmp( &(m_vi[n]), &(other.m_vi[n]), sizeof(f4vector) ) != 0) return false; if (memcmp( &(m_iv[n]), &(other.m_iv[n]), sizeof(f4vector) ) != 0) return false; if (memcmp( &(m_ii[n]), &(other.m_ii[n]), sizeof(f4vector) ) != 0) return false; } return true; } bool SSE_coeff::operator!=( const SSE_coeff& other ) const { return !(*this == other); } bool SSE_coeff::operator<( const SSE_coeff& other ) const { for (int n=0; n<3; n++) { for (int c=0; c<4; c++) { if (m_vv[n].f[c] > other.m_vv[n].f[c]) return false; if (m_vv[n].f[c] < other.m_vv[n].f[c]) return true; if (m_vi[n].f[c] > other.m_vi[n].f[c]) return false; if (m_vi[n].f[c] < other.m_vi[n].f[c]) return true; if (m_iv[n].f[c] > other.m_iv[n].f[c]) return false; if (m_iv[n].f[c] < other.m_iv[n].f[c]) return true; if (m_ii[n].f[c] > other.m_ii[n].f[c]) return false; if (m_ii[n].f[c] < other.m_ii[n].f[c]) return true; } } return false; } void SSE_coeff::print( ostream& stream ) const { stream << "SSE_coeff: (" << endl; for (int n=0; n<3; n++) { stream << "n=" << n << ":" << endl; stream << "vv="; for (int c=0; c<4; c++) stream << m_vv[n].f[c] << " "; stream << endl << "vi="; for (int c=0; c<4; c++) stream << m_vi[n].f[c] << " "; stream << endl << "iv="; for (int c=0; c<4; c++) stream << m_iv[n].f[c] << " "; stream << endl << "ii="; for (int c=0; c<4; c++) stream << m_ii[n].f[c] << " "; stream << endl; } stream << ")" << endl; }