double Forwarder::mr_pthread_forward(const Matrix &pi, const Matrix &A, const Matrix &B, const DeviceDescriptor &device_descriptor) const { if(pi.get_width() != 1 || pi.get_height() != A.get_width() || A.get_height() != A.get_width() || B.get_height() != A.get_width() || B.get_width() != orig_alphabet_size) { std::cerr << "Dimensions of input matrices do not match:" << std::endl; std::cerr << "\t" << "pi width: " << pi.get_width() << std::endl; std::cerr << "\t" << "pi height: " << pi.get_height() << std::endl; std::cerr << "\t" << "A width: " << A.get_width() << std::endl; std::cerr << "\t" << "A height: " << A.get_height() << std::endl; std::cerr << "\t" << "B width: " << B.get_width() << std::endl; std::cerr << "\t" << "B height: " << B.get_height() << std::endl; std::exit(-1); } double *symbol2scale; Matrix *symbol2matrix; const std::vector<std::vector< unsigned> > *sequences; std::vector<ProcessingDevice*> devices; size_t numberOfDevices; double loglikelihood; // find alphabet and seqs for given number of states size_t no_states = A.get_width(); size_t alphabet_size = 0; for(std::map<size_t, std::vector<std::vector<unsigned> > >::const_iterator it = nStates2seqs.begin(); it != nStates2seqs.end(); ++it) { if(it->first >= no_states) { sequences = &(it->second); alphabet_size = nStates2alphabet_size.find(it->first)->second; break; } } if(sequences == 0) { sequences = &(nStates2seqs.rbegin()->second); alphabet_size = nStates2alphabet_size.rbegin()->second; } symbol2scale = new double[alphabet_size]; symbol2matrix = new Matrix[alphabet_size]; compute_symbol2scale_and_symbol2matrix(symbol2matrix, symbol2scale, A, B, alphabet_size); numberOfDevices = device_descriptor.getNDevices(); for(unsigned i = 0; i < numberOfDevices; ++i) { devices.push_back(device_descriptor.createDevice(i)); devices[i]->setParameters(&pi, &A, &B, &symbol2pair, symbol2scale, symbol2matrix); devices[i]->setSeqs(sequences); } const size_t length = sequences->size(); const size_t nBlocks = size_t(std::sqrt(length)); MapReduceJobControl control(length, nBlocks); for(unsigned i = 0; i < numberOfDevices; ++i) devices[i]->mapReduceLoglikelihood(control); for(unsigned i = 0; i < numberOfDevices; ++i) devices[i]->join(); loglikelihood = 0.0; for(size_t i = 0; i < nBlocks; ++i) { loglikelihood += control.resultLogLikelihoods[i]; } for(unsigned i = 0; i < devices.size(); ++i) delete devices[i]; delete[] symbol2scale; delete[] symbol2matrix; return loglikelihood; }
double Forwarder::pthread_forward(const Matrix &pi, const Matrix &A, const Matrix &B, const DeviceDescriptor &device_descriptor) const { if(pi.get_width() != 1 || pi.get_height() != A.get_width() || A.get_height() != A.get_width() || B.get_height() != A.get_width() || B.get_width() != orig_alphabet_size) { std::cerr << "Dimensions of input matrices do not match:" << std::endl; std::cerr << "\t" << "pi width: " << pi.get_width() << std::endl; std::cerr << "\t" << "pi height: " << pi.get_height() << std::endl; std::cerr << "\t" << "A width: " << A.get_width() << std::endl; std::cerr << "\t" << "A height: " << A.get_height() << std::endl; std::cerr << "\t" << "B width: " << B.get_width() << std::endl; std::cerr << "\t" << "B height: " << B.get_height() << std::endl; std::exit(-1); } double *symbol2scale; Matrix *symbol2matrix; std::vector<ProcessingDevice*> devices; size_t numberOfDevices; Matrix *result; Matrix *temp; double loglikelihood; size_t head; // find alphabet and seqs for given number of states size_t no_states = A.get_width(); size_t alphabet_size = 0; const std::vector<std::vector< unsigned> > *sequences; for(std::map<size_t, std::vector<std::vector<unsigned> > >::const_iterator it = nStates2seqs.begin(); it != nStates2seqs.end(); ++it) { if(it->first >= no_states) { sequences = &(it->second); alphabet_size = nStates2alphabet_size.find(it->first)->second; break; } } if(sequences == 0) { sequences = &(nStates2seqs.rbegin()->second); alphabet_size = nStates2alphabet_size.rbegin()->second; } symbol2scale = new double[alphabet_size]; symbol2matrix = new Matrix[alphabet_size]; compute_symbol2scale_and_symbol2matrix(symbol2matrix, symbol2scale, A, B, alphabet_size); result = new Matrix(); temp = new Matrix(); numberOfDevices = device_descriptor.getNDevices(); for(unsigned i = 0; i < numberOfDevices; ++i) { devices.push_back(device_descriptor.createDevice(i)); devices[i]->setParameters(&pi, &A, &B, &symbol2pair, symbol2scale, symbol2matrix); } loglikelihood = 0.0; for(std::vector<std::vector<unsigned> >::const_iterator it = sequences->begin(); it != sequences->end(); ++it) { for(unsigned i = 0; i < numberOfDevices; ++i) { devices[i]->setSeq(&(*it)); } const size_t length = it->size(); const size_t nBlocks = size_t(std::sqrt(length)); Stage2JobControl control(length, nBlocks); devices[0]->likelihoodVector(control); for(unsigned i = 1; i < numberOfDevices; ++i) devices[i]->likelihoodMatrix(control); for(unsigned i = 0; i < numberOfDevices; ++i) devices[i]->join(); head = control.headBlock - 1; Matrix::copy(*control.resultMatrices[head], *result); loglikelihood += control.resultLogLikelihoods[head]; for(size_t i = head + 1; i < nBlocks; ++i) { Matrix::mult(*control.resultMatrices[i], *result, *temp); std::swap(result, temp); loglikelihood += LinearSpace::toLogSpace(result->normalize()) + control.resultLogLikelihoods[i]; } } for(unsigned i = 0; i < devices.size(); ++i) delete devices[i]; delete result; delete temp; delete[] symbol2scale; delete[] symbol2matrix; return loglikelihood; }