// // reduce.cc // // Copyright (C) 1996 Limit Point Systems, Inc. // // Author: Curtis Janssen // Maintainer: LPS // // This file is part of the SC Toolkit. // // The SC Toolkit is free software; you can redistribute it and/or modify // it under the terms of the GNU Library General Public License as published by // the Free Software Foundation; either version 2, or (at your option) // any later version. // // The SC Toolkit 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 Library General Public License for more details. // // You should have received a copy of the GNU Library General Public License // along with the SC Toolkit; see the file COPYING.LIB. If not, write to // the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. // // The U.S. Government is granted a limited license as per AL 91-7. // #ifdef HAVE_CONFIG_H #include #endif #include using namespace sc; ///////////////////////////////////////////////////////////////////////// // instantiate templates #ifdef EXPLICIT_TEMPLATE_INSTANTIATION template class GrpReduce; template class GrpReduce; template class GrpReduce; template class GrpReduce; template class GrpReduce; template class GrpReduce; template class GrpReduce; template class GrpReduce; template class GrpReduce; template class GrpFunctionReduce; template class GrpFunctionReduce; template class GrpFunctionReduce; template class GrpFunctionReduce; template class GrpFunctionReduce; template class GrpFunctionReduce; template class GrpFunctionReduce; template class GrpFunctionReduce; template class GrpFunctionReduce; template class GrpMinReduce; template class GrpMinReduce; template class GrpMinReduce; template class GrpMinReduce; template class GrpMinReduce; template class GrpMinReduce; template class GrpMinReduce; template class GrpMinReduce; template class GrpMinReduce; template class GrpMaxReduce; template class GrpMaxReduce; template class GrpMaxReduce; template class GrpMaxReduce; template class GrpMaxReduce; template class GrpMaxReduce; template class GrpMaxReduce; template class GrpMaxReduce; template class GrpMaxReduce; template class GrpSumReduce; template class GrpSumReduce; template class GrpSumReduce; template class GrpSumReduce; template class GrpSumReduce; template class GrpSumReduce; template class GrpSumReduce; template class GrpSumReduce; template class GrpSumReduce; template class GrpProductReduce; template class GrpProductReduce; template class GrpProductReduce; template class GrpProductReduce; template class GrpProductReduce; template class GrpProductReduce; template class GrpProductReduce; template class GrpProductReduce; template class GrpProductReduce; template class GrpArithmeticOrReduce; template class GrpArithmeticOrReduce; template class GrpArithmeticOrReduce; template class GrpArithmeticOrReduce; template class GrpArithmeticOrReduce; template class GrpArithmeticOrReduce; template class GrpArithmeticOrReduce; template class GrpArithmeticAndReduce; template class GrpArithmeticAndReduce; template class GrpArithmeticAndReduce; template class GrpArithmeticAndReduce; template class GrpArithmeticAndReduce; template class GrpArithmeticAndReduce; template class GrpArithmeticAndReduce; template class GrpArithmeticXOrReduce; template class GrpArithmeticXOrReduce; template class GrpArithmeticXOrReduce; template class GrpArithmeticXOrReduce; template class GrpArithmeticXOrReduce; template class GrpArithmeticXOrReduce; template class GrpArithmeticXOrReduce; #endif ///////////////////////////////////////////////////////////////////////// // sum reduction members template void do_sum(MessageGrp* grp, T* data, int n, T* tmp, int target) { GrpSumReduce gred; grp->reduce(data, n, gred, tmp, target); } void MessageGrp::sum(double* data, int n, double* tmp, int target) { do_sum(this, data, n, tmp, target); } void MessageGrp::sum(unsigned int* data, int n, unsigned int* tmp, int target) { do_sum(this, data, n, tmp, target); } void MessageGrp::sum(int* data, int n, int* tmp, int target) { do_sum(this, data, n, tmp, target); } void MessageGrp::sum(char* data, int n, char* tmp, int target) { do_sum(this, data, n, tmp, target); } void MessageGrp::sum(unsigned char* data, int n, unsigned char* tmp, int target) { do_sum(this, data, n, tmp, target); } void MessageGrp::sum(signed char* data, int n, signed char* tmp, int target) { do_sum(this, data, n, tmp, target); } ///////////////////////////////////////////////////////////////////////// // min reduction members template void do_max(MessageGrp* grp, T* data, int n, T* tmp, int target) { GrpMaxReduce gred; grp->reduce(data, n, gred, tmp, target); } void MessageGrp::max(double* data, int n, double* tmp, int target) { do_max(this, data, n, tmp, target); } void MessageGrp::max(unsigned int* data, int n, unsigned int* tmp, int target) { do_max(this, data, n, tmp, target); } void MessageGrp::max(int* data, int n, int* tmp, int target) { do_max(this, data, n, tmp, target); } void MessageGrp::max(char* data, int n, char* tmp, int target) { do_max(this, data, n, tmp, target); } void MessageGrp::max(unsigned char* data, int n, unsigned char* tmp, int target) { do_max(this, data, n, tmp, target); } void MessageGrp::max(signed char* data, int n, signed char* tmp, int target) { do_max(this, data, n, tmp, target); } ///////////////////////////////////////////////////////////////////////// // max reduction members template void do_min(MessageGrp* grp, T* data, int n, T* tmp, int target) { GrpMinReduce gred; grp->reduce(data, n, gred, tmp, target); } void MessageGrp::min(double* data, int n, double* tmp, int target) { do_min(this, data, n, tmp, target); } void MessageGrp::min(unsigned int* data, int n, unsigned int* tmp, int target) { do_min(this, data, n, tmp, target); } void MessageGrp::min(int* data, int n, int* tmp, int target) { do_min(this, data, n, tmp, target); } void MessageGrp::min(char* data, int n, char* tmp, int target) { do_min(this, data, n, tmp, target); } void MessageGrp::min(unsigned char* data, int n, unsigned char* tmp, int target) { do_min(this, data, n, tmp, target); } void MessageGrp::min(signed char* data, int n, signed char* tmp, int target) { do_min(this, data, n, tmp, target); } ///////////////////////////////////////////////////////////////////////// // generic reduction void MessageGrp::reduce(double* data, int n, GrpReduce& red, double* scratch, int target) { int tgop_max = gop_max_/sizeof(double); if (tgop_max == 0) tgop_max = gop_max_?1:n; int passed_scratch; if (!scratch) { scratch = new double[n>tgop_max?tgop_max:n]; passed_scratch = 0; } else passed_scratch = 1; Ref i(topology_->global_msg_iter(this, (target== -1?0:target))); for (i->backwards(); !i->done(); i->next()) { for (int idat=0; idatn)?(n-idat):tgop_max; if (i->send()) { send(i->sendto(), &data[idat], ndat); } if (i->recv()) { recv(i->recvfrom(), scratch, ndat); red.reduce(&data[idat], scratch, ndat); } } if (n > tgop_max) sync(); } if (target == -1) { bcast(data, n, 0); } if (!passed_scratch) delete[] scratch; } void MessageGrp::reduce(unsigned int* data, int n, GrpReduce& red, unsigned int* scratch, int target) { int tgop_max = gop_max_/sizeof(unsigned int); if (tgop_max == 0) tgop_max = gop_max_?1:n; int passed_scratch; if (!scratch) { scratch = new unsigned int[n>tgop_max?tgop_max:n]; passed_scratch = 0; } else passed_scratch = 1; Ref i(topology_->global_msg_iter(this, (target== -1?0:target))); for (i->backwards(); !i->done(); i->next()) { for (int idat=0; idatn)?(n-idat):tgop_max; if (i->send()) { send(i->sendto(), &data[idat], ndat); } if (i->recv()) { recv(i->recvfrom(), scratch, ndat); red.reduce(&data[idat], scratch, ndat); } } if (n > tgop_max) sync(); } if (target == -1) { bcast(data, n, 0); } if (!passed_scratch) delete[] scratch; } void MessageGrp::reduce(int* data, int n, GrpReduce& red, int* scratch, int target) { int tgop_max = gop_max_/sizeof(int); if (tgop_max == 0) tgop_max = gop_max_?1:n; int passed_scratch; if (!scratch) { scratch = new int[n>tgop_max?tgop_max:n]; passed_scratch = 0; } else passed_scratch = 1; Ref i(topology_->global_msg_iter(this, (target== -1?0:target))); for (i->backwards(); !i->done(); i->next()) { for (int idat=0; idatn)?(n-idat):tgop_max; if (i->send()) { send(i->sendto(), &data[idat], ndat); } if (i->recv()) { recv(i->recvfrom(), scratch, ndat); red.reduce(&data[idat], scratch, ndat); } } if (n > tgop_max) sync(); } if (target == -1) { bcast(data, n, 0); } if (!passed_scratch) delete[] scratch; } void MessageGrp::reduce(char* data, int n, GrpReduce& red, char* scratch, int target) { int tgop_max = gop_max_/sizeof(char); if (tgop_max == 0) tgop_max = gop_max_?1:n; int passed_scratch; if (!scratch) { scratch = new char[n>tgop_max?tgop_max:n]; passed_scratch = 0; } else passed_scratch = 1; Ref i(topology_->global_msg_iter(this, (target== -1?0:target))); for (i->backwards(); !i->done(); i->next()) { for (int idat=0; idatn)?(n-idat):tgop_max; if (i->send()) { send(i->sendto(), &data[idat], ndat); } if (i->recv()) { recv(i->recvfrom(), scratch, ndat); red.reduce(&data[idat], scratch, ndat); } } if (n > tgop_max) sync(); } if (target == -1) { bcast(data, n, 0); } if (!passed_scratch) delete[] scratch; } void MessageGrp::reduce(unsigned char* data, int n, GrpReduce& red, unsigned char* scratch, int target) { int tgop_max = gop_max_/sizeof(unsigned char); if (tgop_max == 0) tgop_max = gop_max_?1:n; int passed_scratch; if (!scratch) { scratch = new unsigned char[n>tgop_max?tgop_max:n]; passed_scratch = 0; } else passed_scratch = 1; Ref i(topology_->global_msg_iter(this, (target== -1?0:target))); for (i->backwards(); !i->done(); i->next()) { for (int idat=0; idatn)?(n-idat):tgop_max; if (i->send()) { send(i->sendto(), &data[idat], ndat); } if (i->recv()) { recv(i->recvfrom(), scratch, ndat); red.reduce(&data[idat], scratch, ndat); } } if (n > tgop_max) sync(); } if (target == -1) { bcast(data, n, 0); } if (!passed_scratch) delete[] scratch; } void MessageGrp::reduce(signed char* data, int n, GrpReduce& red, signed char* scratch, int target) { int tgop_max = gop_max_/sizeof(signed char); if (tgop_max == 0) tgop_max = gop_max_?1:n; int passed_scratch; if (!scratch) { scratch = new signed char[n>tgop_max?tgop_max:n]; passed_scratch = 0; } else passed_scratch = 1; Ref i(topology_->global_msg_iter(this, (target== -1?0:target))); for (i->backwards(); !i->done(); i->next()) { for (int idat=0; idatn)?(n-idat):tgop_max; if (i->send()) { send(i->sendto(), &data[idat], ndat); } if (i->recv()) { recv(i->recvfrom(), scratch, ndat); red.reduce(&data[idat], scratch, ndat); } } if (n > tgop_max) sync(); } if (target == -1) { bcast(data, n, 0); } if (!passed_scratch) delete[] scratch; } void MessageGrp::reduce(short* data, int n, GrpReduce& red, short* scratch, int target) { int tgop_max = gop_max_/sizeof(short); if (tgop_max == 0) tgop_max = gop_max_?1:n; int passed_scratch; if (!scratch) { scratch = new short[n>tgop_max?tgop_max:n]; passed_scratch = 0; } else passed_scratch = 1; Ref i(topology_->global_msg_iter(this, (target== -1?0:target))); for (i->backwards(); !i->done(); i->next()) { for (int idat=0; idatn)?(n-idat):tgop_max; if (i->send()) { send(i->sendto(), &data[idat], ndat); } if (i->recv()) { recv(i->recvfrom(), scratch, ndat); red.reduce(&data[idat], scratch, ndat); } } if (n > tgop_max) sync(); } if (target == -1) { bcast(data, n, 0); } if (!passed_scratch) delete[] scratch; } void MessageGrp::reduce(float* data, int n, GrpReduce& red, float* scratch, int target) { int tgop_max = gop_max_/sizeof(float); if (tgop_max == 0) tgop_max = gop_max_?1:n; int passed_scratch; if (!scratch) { scratch = new float[n>tgop_max?tgop_max:n]; passed_scratch = 0; } else passed_scratch = 1; Ref i(topology_->global_msg_iter(this, (target== -1?0:target))); for (i->backwards(); !i->done(); i->next()) { for (int idat=0; idatn)?(n-idat):tgop_max; if (i->send()) { send(i->sendto(), &data[idat], ndat); } if (i->recv()) { recv(i->recvfrom(), scratch, ndat); red.reduce(&data[idat], scratch, ndat); } } if (n > tgop_max) sync(); } if (target == -1) { bcast(data, n, 0); } if (!passed_scratch) delete[] scratch; } void MessageGrp::reduce(long* data, int n, GrpReduce& red, long* scratch, int target) { int tgop_max = gop_max_/sizeof(long); if (tgop_max == 0) tgop_max = gop_max_?1:n; int passed_scratch; if (!scratch) { scratch = new long[n>tgop_max?tgop_max:n]; passed_scratch = 0; } else passed_scratch = 1; Ref i(topology_->global_msg_iter(this, (target== -1?0:target))); for (i->backwards(); !i->done(); i->next()) { for (int idat=0; idatn)?(n-idat):tgop_max; if (i->send()) { send(i->sendto(), &data[idat], ndat); } if (i->recv()) { recv(i->recvfrom(), scratch, ndat); red.reduce(&data[idat], scratch, ndat); } } if (n > tgop_max) sync(); } if (target == -1) { bcast(data, n, 0); } if (!passed_scratch) delete[] scratch; } #ifdef EXPLICIT_TEMPLATE_INSTANTIATION #define INSTANTIATE_DO_X(func,type) \ template void func(MessageGrp*, type *, int, type *, int) INSTANTIATE_DO_X(do_sum,unsigned int); INSTANTIATE_DO_X(do_sum,int); INSTANTIATE_DO_X(do_sum,double); INSTANTIATE_DO_X(do_sum,char); INSTANTIATE_DO_X(do_sum,unsigned char); INSTANTIATE_DO_X(do_sum,signed char); INSTANTIATE_DO_X(do_max,unsigned int); INSTANTIATE_DO_X(do_max,int); INSTANTIATE_DO_X(do_max,double); INSTANTIATE_DO_X(do_max,char); INSTANTIATE_DO_X(do_max,unsigned char); INSTANTIATE_DO_X(do_max,signed char); INSTANTIATE_DO_X(do_min,unsigned int); INSTANTIATE_DO_X(do_min,int); INSTANTIATE_DO_X(do_min,double); INSTANTIATE_DO_X(do_min,char); INSTANTIATE_DO_X(do_min,unsigned char); INSTANTIATE_DO_X(do_min,signed char); #endif ///////////////////////////////////////////////////////////////////////////// // Local Variables: // mode: c++ // c-file-style: "CLJ" // End: