Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

PLMPI.cc

Go to the documentation of this file.
00001 // -*- C++ -*- 00002 00003 // PLearn (A C++ Machine Learning Library) 00004 // Copyright (C) 2001 Pascal Vincent 00005 // 00006 00007 // Redistribution and use in source and binary forms, with or without 00008 // modification, are permitted provided that the following conditions are met: 00009 // 00010 // 1. Redistributions of source code must retain the above copyright 00011 // notice, this list of conditions and the following disclaimer. 00012 // 00013 // 2. Redistributions in binary form must reproduce the above copyright 00014 // notice, this list of conditions and the following disclaimer in the 00015 // documentation and/or other materials provided with the distribution. 00016 // 00017 // 3. The name of the authors may not be used to endorse or promote 00018 // products derived from this software without specific prior written 00019 // permission. 00020 // 00021 // THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 00022 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00023 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 00024 // NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00025 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 00026 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00027 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00028 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00029 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00030 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00031 // 00032 // This file is part of the PLearn library. For more information on the PLearn 00033 // library, go to the PLearn Web site at www.plearn.org 00034 00035 /* ******************************************************* 00036 * $Id: PLMPI.cc,v 1.4 2004/07/21 16:30:54 chrish42 Exp $ 00037 * This file is part of the PLearn library. 00038 ******************************************************* */ 00039 00040 #include "PLMPI.h" 00041 #include "string.h" 00042 #include <plearn/base/plerror.h> 00043 #include <stdio.h> 00044 00045 namespace PLearn { 00046 using namespace std; 00047 00048 00049 streambuf* PLMPI::new_cin_buf = 0; 00050 00051 #if USING_MPI 00052 bool PLMPI::using_mpi = true; 00053 #else 00054 bool PLMPI::using_mpi = false; 00055 #endif 00056 00057 bool PLMPI::synchronized = true; 00058 00059 int PLMPI::size = 0; 00060 int PLMPI::rank = 0; 00061 00062 PStream PLMPI::mycout; 00063 PStream PLMPI::mycerr; 00064 PStream PLMPI::mycin; 00065 00066 int PLMPI::tag = 2909; 00067 00068 void PLMPI::exchangeBlocks(double* data, int n, int blocksize, double* buffer) 00069 { 00070 //#if USING_MPI 00071 int blockstart = PLMPI::rank*blocksize; 00072 //fprintf(stderr,"blockstart = %d\n",blockstart); 00073 int theblocksize = blocksize; 00074 int diff=n-blockstart; 00075 if (blocksize>diff) theblocksize=diff; 00076 if (theblocksize<=0) 00077 PLERROR("PLMPI::exchangeBlocks with block of size %d (b=%d,n=%d,r=%d,N=%d)", 00078 theblocksize,blocksize,n,PLMPI::rank,PLMPI::size); 00079 //fprintf(stderr,"theblocksize = %d\n",theblocksize); 00080 if (blocksize*PLMPI::size==n && buffer) 00081 { 00082 memcpy(buffer,&data[blockstart],theblocksize*sizeof(double)); 00083 #if USING_MPI 00084 MPI_Allgather(buffer,blocksize,MPI_DOUBLE, 00085 data,blocksize,MPI_DOUBLE,MPI_COMM_WORLD); 00086 #endif 00087 } 00088 else 00089 { 00090 for (int i=0;i<PLMPI::size;i++) 00091 { 00092 int bstart = i*blocksize; 00093 diff = n-bstart; 00094 int bsize = blocksize; 00095 if (bsize>diff) bsize=diff; 00096 //if (i==PLMPI::rank) 00097 //{ 00098 //fprintf(stderr,"start broadcast of %d, bstart=%d, size=%d\n",i,bstart,bsize); 00099 //for (int j=0;j<bsize;j++) 00100 //cerr << data[bstart+j] << endl; 00101 //} 00102 #if USING_MPI 00103 MPI_Bcast(&data[bstart],bsize,MPI_DOUBLE,i,MPI_COMM_WORLD); 00104 #endif 00105 //printf("done broadcast of %d",i); 00106 } 00107 } 00108 //#endif 00109 } 00110 00111 void PLMPI::exchangeBlocks(float* data, int n, int blocksize, float* buffer) 00112 { 00113 //#if USING_MPI 00114 int blockstart = PLMPI::rank*blocksize; 00115 //fprintf(stderr,"blockstart = %d\n",blockstart); 00116 int theblocksize = blocksize; 00117 int diff=n-blockstart; 00118 if (blocksize>diff) theblocksize=diff; 00119 if (theblocksize<=0) 00120 PLERROR("PLMPI::exchangeBlocks with block of size %d (b=%d,n=%d,r=%d,N=%d)", 00121 theblocksize,blocksize,n,PLMPI::rank,PLMPI::size); 00122 //fprintf(stderr,"theblocksize = %d\n",theblocksize); 00123 if (blocksize*PLMPI::size==n && buffer) 00124 { 00125 memcpy(buffer,&data[blockstart],theblocksize*sizeof(float)); 00126 #if USING_MPI 00127 MPI_Allgather(buffer,blocksize,MPI_FLOAT, 00128 data,blocksize,MPI_FLOAT,MPI_COMM_WORLD); 00129 #endif 00130 } 00131 else 00132 { 00133 for (int i=0;i<PLMPI::size;i++) 00134 { 00135 int bstart = i*blocksize; 00136 diff = n-bstart; 00137 int bsize = blocksize; 00138 if (bsize>diff) bsize=diff; 00139 //if (i==PLMPI::rank) 00140 //{ 00141 //fprintf(stderr,"start broadcast of %d, bstart=%d, size=%d\n",i,bstart,bsize); 00142 //for (int j=0;j<bsize;j++) 00143 //cerr << data[bstart+j] << endl; 00144 //} 00145 #if USING_MPI 00146 MPI_Bcast(&data[bstart],bsize,MPI_FLOAT,i,MPI_COMM_WORLD); 00147 #endif 00148 //printf("done broadcast of %d",i); 00149 } 00150 } 00151 //#endif 00152 } 00153 00154 void PLMPI::exchangeColumnBlocks(Mat sourceBlock, Mat destBlocks) 00155 { 00156 #if USING_MPI 00157 int width = sourceBlock.width(); 00158 int length = sourceBlock.length(); 00159 00160 int total_width = destBlocks.width(); 00161 00162 if (total_width%PLMPI::size == 0) // dest width is a multiple of size 00163 { 00164 for (int i=0; i<length; i++) 00165 { 00166 MPI_Allgather(sourceBlock[i],width,PLMPI_REAL, 00167 destBlocks[i],width,PLMPI_REAL,MPI_COMM_WORLD); 00168 } 00169 } 00170 else // last block has different width 00171 { 00172 int size_minus_one = PLMPI::size-1; 00173 int* counts = (int*)malloc(sizeof(int)*PLMPI::size); 00174 int* displs = (int*)malloc(sizeof(int)*PLMPI::size); 00175 int* ptr_counts = counts; 00176 int* ptr_displs = displs; 00177 int norm_width = total_width / PLMPI::size + 1; // width of all blocks except last 00178 int last_width = total_width - norm_width*size_minus_one; // width of last block 00179 if (last_width<=0) 00180 PLERROR("In PLMPI::exchangeColumnsBlocks: unproper choice of processes (%d) for matrix width (%d) leads " 00181 "to width = %d for first mats and width = %d for last mat.",PLMPI::size,total_width,norm_width,last_width); 00182 // sanity check 00183 if (PLMPI::rank==size_minus_one) 00184 { 00185 if (width!=last_width) 00186 PLERROR("In PLMPI::exchangeColumnsBlocks: width of last block is %d, should be %d.",width,last_width); 00187 } 00188 else 00189 if (width!=norm_width) 00190 PLERROR("In PLMPI::exchangeColumnsBlocks: width of block %d is %d, should be %d.",PLMPI::rank,width,last_width); 00191 for (int i=0;i<size_minus_one;i++) 00192 { 00193 *ptr_counts++ = norm_width; 00194 *ptr_displs++ = norm_width*i; 00195 } 00196 // last block 00197 *ptr_counts = last_width; 00198 *ptr_displs = norm_width*size_minus_one; 00199 for (int i=0; i<length; i++) 00200 { 00201 MPI_Allgatherv(sourceBlock[i],width,PLMPI_REAL, 00202 destBlocks[i],counts,displs,PLMPI_REAL,MPI_COMM_WORLD); 00203 } 00204 free(counts); 00205 free(displs); 00206 } 00207 #else 00208 PLWARNING("PLMPI::exchangeColumnsBlocks: in order to use this function, you should recompile with the flag USING_MPI set to 1."); 00209 #endif 00210 } 00211 00212 00213 00214 00215 00216 00217 00218 00219 00220 } // end of namespace PLearn

Generated on Tue Aug 17 16:01:48 2004 for PLearn by doxygen 1.3.7