escript
Revision_
|
00001 00002 /***************************************************************************** 00003 * 00004 * Copyright (c) 2003-2014 by University of Queensland 00005 * http://www.uq.edu.au 00006 * 00007 * Primary Business: Queensland, Australia 00008 * Licensed under the Open Software License version 3.0 00009 * http://www.opensource.org/licenses/osl-3.0.php 00010 * 00011 * Development until 2012 by Earth Systems Science Computational Center (ESSCC) 00012 * Development 2012-2013 by School of Earth Sciences 00013 * Development from 2014 by Centre for Geoscience Computing (GeoComp) 00014 * 00015 *****************************************************************************/ 00016 00017 00018 /****************************************************************************/ 00019 00020 /* Paso: coupler */ 00021 00022 /****************************************************************************/ 00023 00024 /* Author: Lutz Gross, l.gross@uq.edu.au */ 00025 00026 /****************************************************************************/ 00027 00028 #ifndef __PASO_COUPLER_H__ 00029 #define __PASO_COUPLER_H__ 00030 00031 #include "SharedComponents.h" 00032 00033 namespace paso { 00034 00035 struct Connector; 00036 typedef boost::shared_ptr<Connector> Connector_ptr; 00037 typedef boost::shared_ptr<const Connector> const_Connector_ptr; 00038 00039 struct Coupler; 00040 typedef boost::shared_ptr<Coupler> Coupler_ptr; 00041 typedef boost::shared_ptr<const Coupler> const_Coupler_ptr; 00042 00043 PASO_DLL_API 00044 struct Connector 00045 { 00046 SharedComponents_ptr send; 00047 SharedComponents_ptr recv; 00048 Esys_MPIInfo* mpi_info; 00049 00050 Connector(SharedComponents_ptr s, SharedComponents_ptr r) 00051 { 00052 Esys_resetError(); 00053 if (s->mpi_info != r->mpi_info) { 00054 Esys_setError(SYSTEM_ERROR, 00055 "Connector: send and recv MPI communicators don't match."); 00056 } else if (s->local_length != r->local_length) { 00057 Esys_setError(SYSTEM_ERROR, 00058 "Connector: local length of send and recv SharedComponents must match."); 00059 } 00060 send = s; 00061 recv = r; 00062 mpi_info = Esys_MPIInfo_getReference(s->mpi_info); 00063 } 00064 00066 ~Connector() { Esys_MPIInfo_free(mpi_info); } 00067 00069 inline Connector_ptr copy() const { return unroll(1); } 00070 00071 inline Connector_ptr unroll(index_t block_size) const 00072 { 00073 SharedComponents_ptr new_send_shcomp, new_recv_shcomp; 00074 Connector_ptr out; 00075 if (block_size > 1) { 00076 new_send_shcomp.reset(new SharedComponents(send->local_length, 00077 send->numNeighbors, send->neighbor, 00078 send->shared, send->offsetInShared, 00079 block_size, 0, mpi_info)); 00080 00081 new_recv_shcomp.reset(new SharedComponents(recv->local_length, 00082 recv->numNeighbors, recv->neighbor, 00083 recv->shared, recv->offsetInShared, 00084 block_size, 0, mpi_info)); 00085 } else { 00086 new_send_shcomp = send; 00087 new_recv_shcomp = recv; 00088 } 00089 if (Esys_noError()) 00090 out.reset(new Connector(new_send_shcomp, new_recv_shcomp)); 00091 return out; 00092 } 00093 00094 //inline debug() const 00095 //{ 00096 // for (int i=0; i<recv->numNeighbors; ++i) 00097 // printf("Coupler: %d receive %d data at %d from %d\n", 00098 // s->mpi_info->rank,recv->offsetInShared[i+1]-recv->offsetInShared[i], 00099 // recv->offsetInShared[i],recv->neighbor[i]); 00100 // for (int i=0; i<send->numNeighbors; ++i) 00101 // printf("Coupler: %d send %d data at %d to %d\n", 00102 // s->mpi_info->rank,send->offsetInShared[i+1]-send->offsetInShared[i], 00103 // send->offsetInShared[i],send->neighbor[i]); 00104 //} 00105 }; 00106 00107 00108 PASO_DLL_API 00109 struct Coupler 00110 { 00111 Coupler(Connector_ptr, dim_t blockSize); 00112 ~Coupler(); 00113 00114 void startCollect(const double* in); 00115 double* finishCollect(); 00116 void copyAll(Coupler_ptr target) const; 00117 void fillOverlap(dim_t n, double* x); 00118 void max(dim_t n, double* x); 00119 00120 inline const double* borrowLocalData() const { return data; } 00121 00122 inline const double* borrowRemoteData() const { return recv_buffer; } 00123 00124 inline dim_t getNumSharedComponents() const 00125 { 00126 return connector->send->numSharedComponents; 00127 } 00128 00129 inline dim_t getNumOverlapComponents() const 00130 { 00131 return connector->recv->numSharedComponents; 00132 } 00133 00134 inline dim_t getNumSharedValues() const 00135 { 00136 return getNumSharedComponents() * block_size; 00137 } 00138 00139 inline dim_t getNumOverlapValues() const 00140 { 00141 return getNumOverlapComponents() * block_size; 00142 } 00143 00144 inline dim_t getLocalLength() const 00145 { 00146 return connector->send->local_length; 00147 } 00148 00149 Connector_ptr connector; 00150 dim_t block_size; 00151 bool in_use; 00152 00153 // unmanaged pointer to data to be sent 00154 double* data; 00155 double* send_buffer; 00156 double* recv_buffer; 00157 MPI_Request* mpi_requests; 00158 MPI_Status* mpi_stati; 00159 Esys_MPIInfo* mpi_info; 00160 }; 00161 00162 00163 } // namespace paso 00164 00165 #endif // __PASO_COUPLER_H__ 00166