void newviewGenericAncestral (tree *tr, nodeptr p, boolean atRoot) { if(atRoot) { assert(!tr->multiGene); tr->td[0].count = 1; traversalInfoAncestralRoot(p, &(tr->td[0].ti[0]), &(tr->td[0].count), tr->mxtips, tr->numBranches); if(tr->td[0].count > 1) { #ifdef _USE_PTHREADS masterBarrier(THREAD_NEWVIEW_ANCESTRAL, tr); #else newviewIterativeAncestral(tr); #endif } } else { if(isTip(p->number, tr->mxtips)) return; if(tr->multiGene) assert(0); else { tr->td[0].count = 1; computeTraversalInfo(p, &(tr->td[0].ti[0]), &(tr->td[0].count), tr->mxtips, tr->numBranches); if(tr->td[0].count > 1) { #ifdef _USE_PTHREADS masterBarrier(THREAD_NEWVIEW_ANCESTRAL, tr); #else newviewIterativeAncestral(tr); #endif } } } }
void evaluateGeneric (tree *tr, nodeptr p, boolean fullTraversal) { /* now this may be the entry point of the library to compute the log like at a branch defined by p and p->back == q */ volatile double result = 0.0; nodeptr q = p->back; int i, model; /* set the first entry of the traversal descriptor to contain the indices of nodes p and q */ tr->td[0].ti[0].pNumber = p->number; tr->td[0].ti[0].qNumber = q->number; /* copy the branch lengths of the tree into the first entry of the traversal descriptor. if -M is not used tr->numBranches must be 1 */ for(i = 0; i < tr->numBranches; i++) tr->td[0].ti[0].qz[i] = q->z[i]; /* now compute how many conditionals must be re-computed/re-oriented by newview to be able to calculate the likelihood at the root defined by p and q. */ /* one entry in the traversal descriptor is already used, hence set the tarversal length counter to 1 */ tr->td[0].count = 1; /* do we need to recompute any of the vectors at or below p ? */ if(fullTraversal) { assert(isTip(p->number, tr->mxtips)); computeTraversalInfo(q, &(tr->td[0].ti[0]), &(tr->td[0].count), tr->mxtips, tr->numBranches, FALSE); } else { if(!p->x) computeTraversalInfo(p, &(tr->td[0].ti[0]), &(tr->td[0].count), tr->mxtips, tr->numBranches, TRUE); /* recompute/reorient any descriptors at or below q ? computeTraversalInfo computes and stores the newview() to be executed for the traversal descriptor */ if(!q->x) computeTraversalInfo(q, &(tr->td[0].ti[0]), &(tr->td[0].count), tr->mxtips, tr->numBranches, TRUE); } /* now we copy this partition execute mask into the traversal descriptor which must come from the calling program, the logic of this should not form part of the library */ storeExecuteMaskInTraversalDescriptor(tr); /* also store in the traversal descriptor that something has changed i.e., in the parallel case that the traversal descriptor list of nodes needs to be broadcast once again */ tr->td[0].traversalHasChanged = TRUE; evaluateIterative(tr); if(0) { double *recv = (double *)malloc(sizeof(double) * tr->NumberOfModels); MPI_Allreduce(tr->perPartitionLH, recv, tr->NumberOfModels, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); for(model = 0; model < tr->NumberOfModels; model++) { /* TODO ??? */ /*tr->perPartitionLH[model] = recv[model]; */ result += recv[model]; } rax_free(recv); } else { double *recv = (double *)malloc(sizeof(double) * tr->NumberOfModels); MPI_Reduce(tr->perPartitionLH, recv, tr->NumberOfModels, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD); MPI_Bcast(recv, tr->NumberOfModels, MPI_DOUBLE, 0, MPI_COMM_WORLD); for(model = 0; model < tr->NumberOfModels; model++) { /* TODO ??? */ tr->perPartitionLH[model] = recv[model]; result += recv[model]; } rax_free(recv); } /* set the tree data structure likelihood value to the total likelihood */ tr->likelihood = result; /* MPI_Barrier(MPI_COMM_WORLD); printf("Process %d likelihood: %f\n", processID, tr->likelihood); MPI_Barrier(MPI_COMM_WORLD); */ /* do some bookkeeping to have traversalHasChanged in a consistent state */ tr->td[0].traversalHasChanged = FALSE; }