/* * Class: beagle_BeagleJNIWrapper * Method: createInstance * Signature: (IIIIIIIII[IIJJLbeagle/InstanceDetails;)I */ JNIEXPORT jint JNICALL Java_beagle_BeagleJNIWrapper_createInstance (JNIEnv *env, jobject obj, jint tipCount, jint partialsBufferCount, jint compactBufferCount, jint stateCount, jint patternCount, jint eigenBufferCount, jint matrixBufferCount, jint categoryCount, jint scaleBufferCount, jintArray inResourceList, jint resourceCount, jlong preferenceFlags, jlong requirementFlags, jobject outInstanceDetails) { BeagleInstanceDetails instanceDetails; jint *resourceList = NULL; if (inResourceList != NULL) resourceList = env->GetIntArrayElements(inResourceList, NULL); jint instance = (jint)beagleCreateInstance(tipCount, partialsBufferCount, compactBufferCount, stateCount, patternCount, eigenBufferCount, matrixBufferCount, categoryCount, scaleBufferCount, (int *)resourceList, resourceCount, preferenceFlags, requirementFlags, &instanceDetails); if(inResourceList != NULL) env->ReleaseIntArrayElements(inResourceList, resourceList, JNI_ABORT); if (instance >= 0) { jclass objClass = env->FindClass("beagle/InstanceDetails"); if (objClass == NULL) { printf("NULL returned in FindClass: can't find class: beagle/InstanceDetails\n"); return BEAGLE_ERROR_GENERAL; } jmethodID setResourceNumberMethodID = env->GetMethodID(objClass, "setResourceNumber", "(I)V"); if (setResourceNumberMethodID == NULL) { printf("NULL returned in FindClass: can't find 'setResourceNumber' method in class: beagle/InstanceDetails\n"); return BEAGLE_ERROR_GENERAL; } jmethodID setFlagsMethodID = env->GetMethodID(objClass, "setFlags", "(J)V"); if (setFlagsMethodID == NULL) { printf("NULL returned in FindClass: can't find 'setFlags' method in class: beagle/InstanceDetails\n"); return BEAGLE_ERROR_GENERAL; } env->CallVoidMethod(outInstanceDetails, setResourceNumberMethodID, instanceDetails.resourceNumber); env->CallVoidMethod(outInstanceDetails, setFlagsMethodID, instanceDetails.flags); } return instance; }
void set_beagle_instances(world_fmt *world, boolean instance) { int resource=1;//cpu=0, gpu=1 long i; long ii; long locus = world->locus; beagle_fmt *beagle = world->beagle; for(i=0;i<world->nummutationmodels[locus];i++) { ii = world->sublocistarts[locus] + i; beagle->instance_handle[i] = beagleCreateInstance(world->sumtips, // number of tips 2 * (2 * world->sumtips-1), // total buffers (= total nodes in tree) // twice to accomodate rejections. 0, // number of compact state representation [funny tips] world->mutationmodels[ii].numstates, // number of states (nucleotides etc) world->mutationmodels[ii].numsites, // number of site patterns 1, // number of rate matrices eigen-decomp buffers 2*(2 * world->sumtips - 2),// number of rate matrix buffers (=number of branches) world->mutationmodels[ii].numsiterates,// categoryCount 0, //2*(2 * world->sumtips - 1), number of scaling buffers &resource, // List of resources (?) 1, // Number of resources 0L, // preferenceFlags (see BeagleFlags) 0L // requirementFlags (see BeagleFlags) ); if (beagle->instance_handle[i] < 0) usererror("createInstance returned a negative instance handle (and that's not good)"); // initialize the instance int code = beagleInitializeInstance(beagle->instance_handle[i], NULL); if (code < 0) { usererror("initializeInstance returned a negative error code (and that is bad)\n\n"); } } }
int main( int argc, const char* argv[] ) { // print resource list BeagleResourceList* rList; rList = beagleGetResourceList(); fprintf(stdout, "Available resources:\n"); for (int i = 0; i < rList->length; i++) { fprintf(stdout, "\tResource %i:\n\t\tName : %s\n", i, rList->list[i].name); fprintf(stdout, "\t\tDesc : %s\n", rList->list[i].description); fprintf(stdout, "\t\tFlags:"); printFlags(rList->list[i].supportFlags); fprintf(stdout, "\n"); } fprintf(stdout, "\n"); bool manualScaling = false; bool autoScaling = false; bool gRates = false; // generalized rate categories, separate root buffers // is nucleotides... int stateCount = 4; // get the number of site patterns int nPatterns = strlen(human); int rateCategoryCount = 4; int nRateCats = (gRates ? 1 : rateCategoryCount); int nRootCount = (!gRates ? 1 : rateCategoryCount); int nPartBuffs = 4 + nRootCount; int scaleCount = (manualScaling ? 2 + nRootCount : 0); // initialize the instance BeagleInstanceDetails instDetails; // create an instance of the BEAGLE library int instance = beagleCreateInstance( 3, /**< Number of tip data elements (input) */ nPartBuffs, /**< Number of partials buffers to create (input) */ 0, /**< Number of compact state representation buffers to create (input) */ stateCount, /**< Number of states in the continuous-time Markov chain (input) */ nPatterns, /**< Number of site patterns to be handled by the instance (input) */ 1, /**< Number of rate matrix eigen-decomposition buffers to allocate (input) */ 4, /**< Number of rate matrix buffers (input) */ nRateCats, /**< Number of rate categories (input) */ scaleCount, /**< Number of scaling buffers */ NULL, /**< List of potential resource on which this instance is allowed (input, NULL implies no restriction */ 0, /**< Length of resourceList list (input) */ BEAGLE_FLAG_PRECISION_DOUBLE | BEAGLE_FLAG_PROCESSOR_GPU | (autoScaling ? BEAGLE_FLAG_SCALING_AUTO : 0), /**< Bit-flags indicating preferred implementation charactertistics, see BeagleFlags (input) */ 0, /**< Bit-flags indicating required implementation characteristics, see BeagleFlags (input) */ &instDetails); if (instance < 0) { fprintf(stderr, "Failed to obtain BEAGLE instance\n\n"); exit(1); } int rNumber = instDetails.resourceNumber; fprintf(stdout, "Using resource %i:\n", rNumber); fprintf(stdout, "\tRsrc Name : %s\n",instDetails.resourceName); fprintf(stdout, "\tImpl Name : %s\n", instDetails.implName); fprintf(stdout, "\tImpl Desc : %s\n", instDetails.implDescription); fprintf(stdout, "\tFlags:"); printFlags(instDetails.flags); fprintf(stdout, "\n\n"); if (!(instDetails.flags & BEAGLE_FLAG_SCALING_AUTO)) autoScaling = false; // beagleSetTipStates(instance, 0, getStates(human)); // beagleSetTipStates(instance, 1, getStates(chimp)); // beagleSetTipStates(instance, 2, getStates(gorilla)); // set the sequences for each tip using partial likelihood arrays double *humanPartials = getPartials(human); double *chimpPartials = getPartials(chimp); double *gorillaPartials = getPartials(gorilla); beagleSetTipPartials(instance, 0, humanPartials); beagleSetTipPartials(instance, 1, chimpPartials); beagleSetTipPartials(instance, 2, gorillaPartials); //#ifdef _WIN32 // std::vector<double> rates(rateCategoryCount); //#else // double rates[rateCategoryCount]; //#endif // for (int i = 0; i < rateCategoryCount; i++) { // rates[i] = 1.0; // } double rates[4] = { 0.03338775, 0.25191592, 0.82026848, 2.89442785 }; // create base frequency array double freqs[16] = { 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25 }; // create an array containing site category weights double* weights = (double*) malloc(sizeof(double) * rateCategoryCount); for (int i = 0; i < rateCategoryCount; i++) { weights[i] = 1.0/rateCategoryCount; } double* patternWeights = (double*) malloc(sizeof(double) * nPatterns); for (int i = 0; i < nPatterns; i++) { patternWeights[i] = 1.0; } // an eigen decomposition for the JC69 model double evec[4 * 4] = { 1.0, 2.0, 0.0, 0.5, 1.0, -2.0, 0.5, 0.0, 1.0, 2.0, 0.0, -0.5, 1.0, -2.0, -0.5, 0.0 }; double ivec[4 * 4] = { 0.25, 0.25, 0.25, 0.25, 0.125, -0.125, 0.125, -0.125, 0.0, 1.0, 0.0, -1.0, 1.0, 0.0, -1.0, 0.0 }; double eval[4] = { 0.0, -1.3333333333333333, -1.3333333333333333, -1.3333333333333333 }; // set the Eigen decomposition beagleSetEigenDecomposition(instance, 0, evec, ivec, eval); beagleSetStateFrequencies(instance, 0, freqs); beagleSetCategoryWeights(instance, 0, weights); beagleSetPatternWeights(instance, patternWeights); // a list of indices and edge lengths int nodeIndices[4] = { 0, 1, 2, 3 }; double edgeLengths[4] = { 0.1, 0.1, 0.2, 0.1 }; int* rootIndices = (int*) malloc(sizeof(int) * nRootCount); int* categoryWeightsIndices = (int*) malloc(sizeof(int) * nRootCount); int* stateFrequencyIndices = (int*) malloc(sizeof(int) * nRootCount); int* cumulativeScalingIndices = (int*) malloc(sizeof(int) * nRootCount); for (int i = 0; i < nRootCount; i++) { rootIndices[i] = 4 + i; categoryWeightsIndices[i] = 0; stateFrequencyIndices[i] = 0; cumulativeScalingIndices[i] = (manualScaling ? 2 + i : BEAGLE_OP_NONE); beagleSetCategoryRates(instance, &rates[i]); // tell BEAGLE to populate the transition matrices for the above edge lengths beagleUpdateTransitionMatrices(instance, // instance 0, // eigenIndex nodeIndices, // probabilityIndices NULL, // firstDerivativeIndices NULL, // secondDerivativeIndices edgeLengths, // edgeLengths 4); // count // create a list of partial likelihood update operations // the order is [dest, destScaling, source1, matrix1, source2, matrix2] BeagleOperation operations[2] = { 3, (manualScaling ? 0 : BEAGLE_OP_NONE), BEAGLE_OP_NONE, 0, 0, 1, 1, rootIndices[i], (manualScaling ? 1 : BEAGLE_OP_NONE), BEAGLE_OP_NONE, 2, 2, 3, 3 }; if (manualScaling) beagleResetScaleFactors(instance, cumulativeScalingIndices[i]); // update the partials beagleUpdatePartials(instance, // instance operations, // eigenIndex 2, // operationCount cumulativeScalingIndices[i]);// cumulative scaling index } if (autoScaling) { int scaleIndices[2] = {3, 4}; beagleAccumulateScaleFactors(instance, scaleIndices, 2, BEAGLE_OP_NONE); } double *patternLogLik = (double*)malloc(sizeof(double) * nPatterns); double logL = 0.0; int returnCode = 0; // calculate the site likelihoods at the root node returnCode = beagleCalculateRootLogLikelihoods(instance, // instance (const int *)rootIndices,// bufferIndices (const int *)categoryWeightsIndices, // weights (const int *)stateFrequencyIndices, // stateFrequencies cumulativeScalingIndices,// cumulative scaling index nRootCount, // count &logL); // outLogLikelihoods if (returnCode < 0) { fprintf(stderr, "Failed to calculate root likelihood\n\n"); } else { beagleGetSiteLogLikelihoods(instance, patternLogLik); double sumLogL = 0.0; for (int i = 0; i < nPatterns; i++) { sumLogL += patternLogLik[i] * patternWeights[i]; // std::cerr << "site lnL[" << i << "] = " << patternLogLik[i] << '\n'; } fprintf(stdout, "logL = %.5f (PAUP logL = -1498.89812)\n", logL); fprintf(stdout, "sumLogL = %.5f\n", sumLogL); } // no rate heterogeneity: // fprintf(stdout, "logL = %.5f (PAUP logL = -1574.63623)\n\n", logL); free(weights); free(patternWeights); free(rootIndices); free(categoryWeightsIndices); free(stateFrequencyIndices); free(cumulativeScalingIndices); free(patternLogLik); free(humanPartials); free(chimpPartials); free(gorillaPartials); beagleFinalizeInstance(instance); #ifdef _WIN32 std::cout << "\nPress ENTER to exit...\n"; fflush( stdout); fflush( stderr); getchar(); #endif }
int create_beagle_instance(t_tree *tree, int quiet, option* io) { if(UNINITIALIZED != tree->b_inst){ // fprintf(stdout,"\n\tWARNING: Creating a BEAGLE instance on a tree with an existing BEAGLE instance:%d\n",tree->b_inst); } if(!quiet){ // print_beagle_resource_list(); } int i; BeagleInstanceDetails inst_d; int num_rate_catg = tree->mod->ras->n_catg; int num_branches = 2*tree->n_otu-1; //rooted tree //Recall that in PhyML, each edge has a "left" and "right" partial vectors. Therefore, //in BEAGLE we have 2*num_branches number of partials. //BEAGLE's partials buffer = [ tax1, tax2, ..., taxN, b1Left, b2Left, b3Left,...,bMLeft, b1Rght, b2Rght, b3Rght,...,bMRght] (N taxa, M branches) int num_partials = 2*(tree->n_otu + num_branches); /* TODO: This does not seem correct; suspect poor indexing elsewhere */ /* In update_operations, indexes range from 0 to almost 2 (n_otu + num_branches), but not all integers are used */ int resourceList[1]; resourceList[0] = io->beagle_resource; // DUMP_I(tree->n_otu, num_rate_catg, num_partials, num_branches, tree->mod->ns, tree->n_pattern, tree->mod->whichmodel); int beagle_inst = beagleCreateInstance( tree->n_otu, /**< Number of tip data elements (input) */ num_partials, /**< Number of partial buffer (input) */ /* PhyML uses partials */ 0, /**< Number of compact state representation buffers to create (input) */ tree->mod->ns, /**< Number of states in the continuous-time Markov chain (input) */ tree->n_pattern, /**< Number of site patterns to be handled by the instance (input) */ 1, /**< Number of rate matrix eigen-decomposition,state freqs, and category weight buffers*/ num_branches, /**< Number of rate matrix buffers (input) */ num_rate_catg, /**< Number of rate categories (input) */ -1, /**< Number of scaling buffers. Unused because we use SCALING_ALWAYS */ resourceList, /**< List of potential resource on which this instance is allowed (input, NULL implies no restriction */ 1, /**< Length of resourceList list (input) */ BEAGLE_FLAG_FRAMEWORK_CPU | BEAGLE_FLAG_PROCESSOR_CPU | BEAGLE_FLAG_SCALING_ALWAYS | BEAGLE_FLAG_EIGEN_REAL | ((sizeof(float)==sizeof(phydbl)) ? BEAGLE_FLAG_PRECISION_SINGLE:BEAGLE_FLAG_PRECISION_DOUBLE), 0, /**< Bit-flags indicating required implementation characteristics, see BeagleFlags (input) */ &inst_d); if (beagle_inst < 0){ fprintf(stderr, "beagleCreateInstance() failed:%i\n\n",beagle_inst); return beagle_inst; } if(!quiet){ fprintf(stdout, "\n\tUnique BEAGLE instance id:%i\n", beagle_inst); print_beagle_instance_details(&inst_d); } //Set the tips for(i=0; i<2*tree->n_otu-1; ++i) //taxa+internal nodes { // Print_Tip_Partials(tree, tree->a_nodes[i]); if(tree->a_nodes[i]->tax) { assert(tree->a_nodes[i]->c_seq->len == tree->n_pattern); // number of compacts sites == number of distinct site patterns double* tip = short_to_double(tree->a_nodes[i]->b[0]->p_lk_tip_r, tree->n_pattern*tree->mod->ns); //The tip states are stored on the branch leading to the tip //Recall we store tip partials on the branch leading to the tip, rather than the tip itself. int ret = beagleSetTipPartials(beagle_inst, tree->a_nodes[i]->b[0]->p_lk_tip_idx, tip); if(ret<0){ fprintf(stderr, "beagleSetTipPartials() on instance %i failed:%i\n\n",beagle_inst,ret); Free(tip); return ret; } Free(tip); } } //Set the pattern weights double* pwts = int_to_double(tree->data->wght,tree->n_pattern); //BTW, These weights are absolute counts, and not freqs int ret = beagleSetPatternWeights(beagle_inst, pwts); if(ret<0){ fprintf(stderr, "beagleSetPatternWeights() on instance %i failed:%i\n\n",beagle_inst,ret); Free(pwts); return ret; } Free(pwts); tree->mod->b_inst=beagle_inst; update_beagle_ras(tree->mod); update_beagle_efrqs(tree->mod); return beagle_inst; }
int main( int argc, const char* argv[] ) { bool scaling = true; // is nucleotides... int stateCount = 4; // get the number of site patterns int nPatterns = strlen(human); int rateCategoryCount = 4; int scaleCount = (scaling ? 3 : 0); BeagleInstanceDetails instDetails; // create an instance of the BEAGLE library int instance = beagleCreateInstance( 3, /**< Number of tip data elements (input) */ 5, /**< Number of partials buffers to create (input) */ 0, /**< Number of compact state representation buffers to create (input) */ stateCount, /**< Number of states in the continuous-time Markov chain (input) */ nPatterns, /**< Number of site patterns to be handled by the instance (input) */ 1, /**< Number of rate matrix eigen-decomposition buffers to allocate (input) */ 4, /**< Number of rate matrix buffers (input) */ rateCategoryCount,/**< Number of rate categories (input) */ scaleCount, /**< Number of scaling buffers */ NULL, /**< List of potential resource on which this instance is allowed (input, NULL implies no restriction */ 0, /**< Length of resourceList list (input) */ BEAGLE_FLAG_PROCESSOR_GPU, /**< Bit-flags indicating preferred implementation charactertistics, see BeagleFlags (input) */ 0 #ifndef JC | BEAGLE_FLAG_EIGEN_COMPLEX #endif , /**< Bit-flags indicating required implementation characteristics, see BeagleFlags (input) */ &instDetails); if (instance < 0) { fprintf(stderr, "Failed to obtain BEAGLE instance\n\n"); exit(1); } int rNumber = instDetails.resourceNumber; fprintf(stdout, "Using resource %i:\n", rNumber); fprintf(stdout, "\tRsrc Name : %s\n",instDetails.resourceName); fprintf(stdout, "\tImpl : %s\n", instDetails.implName); fprintf(stdout, "\tImpl Desc : %s\n", instDetails.implDescription); fprintf(stdout, "\n"); // set the sequences for each tip using partial likelihood arrays double *humanPartials = getPartials(human); double *chimpPartials = getPartials(chimp); double *gorillaPartials = getPartials(gorilla); beagleSetTipPartials(instance, 0, humanPartials); beagleSetTipPartials(instance, 1, chimpPartials); beagleSetTipPartials(instance, 2, gorillaPartials); #ifdef _WIN32 std::vector<double> rates(rateCategoryCount); #else double rates[rateCategoryCount]; #endif for (int i = 0; i < rateCategoryCount; i++) { rates[i] = 1.0; } beagleSetCategoryRates(instance, &rates[0]); double* patternWeights = (double*) malloc(sizeof(double) * nPatterns); for (int i = 0; i < nPatterns; i++) { patternWeights[i] = 1.0; } beagleSetPatternWeights(instance, patternWeights); // create base frequency array double freqs[4] = { 0.25, 0.25, 0.25, 0.25 }; beagleSetStateFrequencies(instance, 0, freqs); // create an array containing site category weights #ifdef _WIN32 std::vector<double> weights(rateCategoryCount); #else double weights[rateCategoryCount]; #endif for (int i = 0; i < rateCategoryCount; i++) { weights[i] = 1.0/rateCategoryCount; } beagleSetCategoryWeights(instance, 0, &weights[0]); #ifndef JC // an eigen decomposition for the 4-state 1-step circulant infinitesimal generator double evec[4 * 4] = { -0.5, 0.6906786606674509, 0.15153543380548623, 0.5, 0.5, -0.15153543380548576, 0.6906786606674498, 0.5, -0.5, -0.6906786606674498, -0.15153543380548617, 0.5, 0.5, 0.15153543380548554, -0.6906786606674503, 0.5 }; double ivec[4 * 4] = { -0.5, 0.5, -0.5, 0.5, 0.6906786606674505, -0.15153543380548617, -0.6906786606674507, 0.15153543380548645, 0.15153543380548568, 0.6906786606674509, -0.15153543380548584, -0.6906786606674509, 0.5, 0.5, 0.5, 0.5 }; double eval[8] = { -2.0, -1.0, -1.0, 0, 0, 1, -1, 0 }; #else // an eigen decomposition for the JC69 model double evec[4 * 4] = { 1.0, 2.0, 0.0, 0.5, 1.0, -2.0, 0.5, 0.0, 1.0, 2.0, 0.0, -0.5, 1.0, -2.0, -0.5, 0.0 }; double ivec[4 * 4] = { 0.25, 0.25, 0.25, 0.25, 0.125, -0.125, 0.125, -0.125, 0.0, 1.0, 0.0, -1.0, 1.0, 0.0, -1.0, 0.0 }; double eval[8] = { 0.0, -1.3333333333333333, -1.3333333333333333, -1.3333333333333333, 0.0, 0.0, 0.0, 0.0 }; #endif // a list of indices and edge lengths int nodeIndices[4] = { 0, 1, 2, 3 }; double edgeLengths[4] = { 0.1, 0.1, 0.2, 0.1 }; // // set the Eigen decomposition // beagleSetEigenDecomposition(instance, 0, evec, ivec, eval); // // // tell BEAGLE to populate the transition matrices for the above edge lengths // beagleUpdateTransitionMatrices(instance, // instance // 0, // eigenIndex // nodeIndices, // probabilityIndices // NULL, // firstDerivativeIndices // NULL, // secondDervativeIndices // edgeLengths, // edgeLengths // 4); // count // set transitionMatrices double* transitionMatrix = (double*) malloc(4 * 4 * 4 * rateCategoryCount * sizeof(double)); double* paddedValues = (double*) malloc(4*sizeof(double)); for(int b=0; b<4; b++) { getTransitionMatrix(eval, evec, ivec, 4, rateCategoryCount, &rates[0], edgeLengths[b], transitionMatrix + b*4*4*rateCategoryCount); paddedValues[b] = 1.0; } beagleSetTransitionMatrices(instance, nodeIndices, transitionMatrix, paddedValues, 4); free(transitionMatrix); // create a list of partial likelihood update operations // the order is [dest, destScaling, source1, matrix1, source2, matrix2] BeagleOperation operations[2] = { 3, (scaling ? 0 : BEAGLE_OP_NONE), BEAGLE_OP_NONE, 0, 0, 1, 1, 4, (scaling ? 1 : BEAGLE_OP_NONE), BEAGLE_OP_NONE, 2, 2, 3, 3 }; int rootIndex = 4; // update the partials beagleUpdatePartials(instance, // instance operations, // eigenIndex 2, // operationCount BEAGLE_OP_NONE); // cumulative scaling index double *patternLogLik = (double*)malloc(sizeof(double) * nPatterns); int cumulativeScalingIndex = (scaling ? 2 : BEAGLE_OP_NONE); if (scaling) { int scalingFactorsCount = 2; int scalingFactorsIndices[2] = {0, 1}; beagleResetScaleFactors(instance, cumulativeScalingIndex); beagleAccumulateScaleFactors(instance, scalingFactorsIndices, scalingFactorsCount, cumulativeScalingIndex); } int categoryWeightsIndex = 0; int stateFrequencyIndex = 0; double logL = 0.0; // calculate the site likelihoods at the root node beagleCalculateRootLogLikelihoods(instance, // instance (const int *)&rootIndex,// bufferIndices &categoryWeightsIndex, // weights &stateFrequencyIndex, // stateFrequencies &cumulativeScalingIndex,// cumulative scaling index 1, // count &logL); // outLogLikelihoods #ifndef JC fprintf(stdout, "logL = %.5f (BEAST = -1665.38544)\n\n", logL); #else fprintf(stdout, "logL = %.5f (PAUP = -1574.63623)\n\n", logL); #endif free(patternWeights); free(patternLogLik); free(humanPartials); free(chimpPartials); free(gorillaPartials); beagleFinalizeInstance(instance); #ifdef _WIN32 std::cout << "\nPress ENTER to exit...\n"; fflush( stdout); fflush( stderr); getchar(); #endif }
/*------------------------------------------------------------------------ | | InitBeagleInstance: create and initialize a beagle instance | -------------------------------------------------------------------------*/ int InitBeagleInstance (ModelInfo *m, int division) { int i, j, k, c, s, *inStates, numPartAmbigTips; double *inPartials; SafeLong *charBits; BeagleInstanceDetails details; long preferedFlags, requiredFlags; int resource; if (m->useBeagle == NO) return ERROR; /* at least one eigen buffer needed */ if (m->nCijkParts == 0) m->nCijkParts = 1; /* allocate memory used by beagle */ m->logLikelihoods = (MrBFlt *) SafeCalloc ((numLocalChains)*m->numChars, sizeof(MrBFlt)); m->inRates = (MrBFlt *) SafeCalloc (m->numGammaCats, sizeof(MrBFlt)); m->branchLengths = (MrBFlt *) SafeCalloc (2*numLocalTaxa, sizeof(MrBFlt)); m->tiProbIndices = (int *) SafeCalloc (2*numLocalTaxa, sizeof(int)); m->inWeights = (MrBFlt *) SafeCalloc (m->numGammaCats*m->nCijkParts, sizeof(MrBFlt)); m->bufferIndices = (int *) SafeCalloc (m->nCijkParts, sizeof(int)); m->eigenIndices = (int *) SafeCalloc (m->nCijkParts, sizeof(int)); m->childBufferIndices = (int *) SafeCalloc (m->nCijkParts, sizeof(int)); m->childTiProbIndices = (int *) SafeCalloc (m->nCijkParts, sizeof(int)); m->cumulativeScaleIndices = (int *) SafeCalloc (m->nCijkParts, sizeof(int)); numPartAmbigTips = 0; if (m->numStates != m->numModelStates) numPartAmbigTips = numLocalTaxa; else { for (i=0; i<numLocalTaxa; i++) { if (m->isPartAmbig[i] == YES) numPartAmbigTips++; } } if (beagleResourceCount == 0) { preferedFlags = beagleFlags; } else { resource = beagleResource[beagleInstanceCount % beagleResourceCount]; preferedFlags = beagleFlags; } requiredFlags = 0L; if (beagleScalingScheme == MB_BEAGLE_SCALE_ALWAYS) requiredFlags |= BEAGLE_FLAG_SCALERS_LOG; //BEAGLE_FLAG_SCALERS_RAW; /* TODO: allocate fewer buffers when nCijkParts > 1 */ /* create beagle instance */ m->beagleInstance = beagleCreateInstance(numLocalTaxa, m->numCondLikes * m->nCijkParts, numLocalTaxa - numPartAmbigTips, m->numModelStates, m->numChars, (numLocalChains + 1) * m->nCijkParts, m->numTiProbs*m->nCijkParts, m->numGammaCats, m->numScalers * m->nCijkParts, (beagleResourceCount == 0 ? NULL : &resource), (beagleResourceCount == 0 ? 0 : 1), preferedFlags, requiredFlags, &details); if (m->beagleInstance < 0) { MrBayesPrint ("%s Failed to start BEAGLE instance\n", spacer); return (ERROR); } else { MrBayesPrint( "\n%s Using BEAGLE resource %i for division %d:", spacer, details.resourceNumber, division+1); #if defined (THREADS_ENABLED) MrBayesPrint( " (%s)\n", (tryToUseThreads ? "threaded" : "non-threaded")); #else MrBayesPrint( " (non-threaded)\n"); #endif MrBayesPrint( "%s Rsrc Name : %s\n", spacer, details.resourceName); MrBayesPrint( "%s Impl Name : %s\n", spacer, details.implName); MrBayesPrint( "%s Flags:", spacer); BeaglePrintFlags(details.flags); MrBayesPrint( "\n"); beagleInstanceCount++; } /* initialize tip data */ inStates = (int *) SafeMalloc (m->numChars * sizeof(int)); if (!inStates) return ERROR; inPartials = (double *) SafeMalloc (m->numChars * m->numModelStates * sizeof(double)); if (!inPartials) return ERROR; for (i=0; i<numLocalTaxa; i++) { if (m->isPartAmbig[i] == NO) { charBits = m->parsSets[i]; for (c=0; c<m->numChars; c++) { for (s=j=0; s<m->numModelStates; s++) { if (IsBitSet(s, charBits)) { inStates[c] = s; j++; } } if (j == m->numModelStates) inStates[c] = j; else assert(j==1); charBits += m->nParsIntsPerSite; } beagleSetTipStates(m->beagleInstance, i, inStates); } else /* if (m->isPartAmbig == YES) */ { k = 0; charBits = m->parsSets[i]; for (c=0; c<m->numChars; c++) { for (s=0; s<m->numModelStates; s++) { if (IsBitSet(s%m->numStates, charBits)) inPartials[k++] = 1.0; else inPartials[k++] = 0.0; } charBits += m->nParsIntsPerSite; } beagleSetTipPartials(m->beagleInstance, i, inPartials); } } free (inStates); free (inPartials); return NO_ERROR; }
void runBeagle(int resource, int stateCount, int ntaxa, int nsites, bool manualScaling, bool autoScaling, bool dynamicScaling, int rateCategoryCount, int nreps, bool fullTiming, bool requireDoublePrecision, bool requireSSE, int compactTipCount, int randomSeed, int rescaleFrequency, bool unrooted, bool calcderivs, bool logscalers, int eigenCount, bool eigencomplex, bool ievectrans, bool setmatrix) { int edgeCount = ntaxa*2-2; int internalCount = ntaxa-1; int partialCount = ((ntaxa+internalCount)-compactTipCount)*eigenCount; int scaleCount = ((manualScaling || dynamicScaling) ? ntaxa : 0); BeagleInstanceDetails instDetails; // create an instance of the BEAGLE library int instance = beagleCreateInstance( ntaxa, /**< Number of tip data elements (input) */ partialCount, /**< Number of partials buffers to create (input) */ compactTipCount, /**< Number of compact state representation buffers to create (input) */ stateCount, /**< Number of states in the continuous-time Markov chain (input) */ nsites, /**< Number of site patterns to be handled by the instance (input) */ eigenCount, /**< Number of rate matrix eigen-decomposition buffers to allocate (input) */ (calcderivs ? (3*edgeCount*eigenCount) : edgeCount*eigenCount),/**< Number of rate matrix buffers (input) */ rateCategoryCount,/**< Number of rate categories */ scaleCount*eigenCount, /**< scaling buffers */ &resource, /**< List of potential resource on which this instance is allowed (input, NULL implies no restriction */ 1, /**< Length of resourceList list (input) */ 0, /**< Bit-flags indicating preferred implementation charactertistics, see BeagleFlags (input) */ (ievectrans ? BEAGLE_FLAG_INVEVEC_TRANSPOSED : BEAGLE_FLAG_INVEVEC_STANDARD) | (logscalers ? BEAGLE_FLAG_SCALERS_LOG : BEAGLE_FLAG_SCALERS_RAW) | (eigencomplex ? BEAGLE_FLAG_EIGEN_COMPLEX : BEAGLE_FLAG_EIGEN_REAL) | (dynamicScaling ? BEAGLE_FLAG_SCALING_DYNAMIC : 0) | (autoScaling ? BEAGLE_FLAG_SCALING_AUTO : 0) | (requireDoublePrecision ? BEAGLE_FLAG_PRECISION_DOUBLE : BEAGLE_FLAG_PRECISION_SINGLE) | (requireSSE ? BEAGLE_FLAG_VECTOR_SSE : BEAGLE_FLAG_VECTOR_NONE), /**< Bit-flags indicating required implementation characteristics, see BeagleFlags (input) */ &instDetails); if (instance < 0) { fprintf(stderr, "Failed to obtain BEAGLE instance\n\n"); return; } int rNumber = instDetails.resourceNumber; fprintf(stdout, "Using resource %i:\n", rNumber); fprintf(stdout, "\tRsrc Name : %s\n",instDetails.resourceName); fprintf(stdout, "\tImpl Name : %s\n", instDetails.implName); if (!(instDetails.flags & BEAGLE_FLAG_SCALING_AUTO)) autoScaling = false; // set the sequences for each tip using partial likelihood arrays gt_srand(randomSeed); // fix the random seed... for(int i=0; i<ntaxa; i++) { if (i >= compactTipCount) { double* tmpPartials = getRandomTipPartials(nsites, stateCount); beagleSetTipPartials(instance, i, tmpPartials); free(tmpPartials); } else { int* tmpStates = getRandomTipStates(nsites, stateCount); beagleSetTipStates(instance, i, tmpStates); free(tmpStates); } } #ifdef _WIN32 std::vector<double> rates(rateCategoryCount); #else double rates[rateCategoryCount]; #endif for (int i = 0; i < rateCategoryCount; i++) { rates[i] = gt_rand() / (double) GT_RAND_MAX; } beagleSetCategoryRates(instance, &rates[0]); double* patternWeights = (double*) malloc(sizeof(double) * nsites); for (int i = 0; i < nsites; i++) { patternWeights[i] = gt_rand() / (double) GT_RAND_MAX; } beagleSetPatternWeights(instance, patternWeights); free(patternWeights); // create base frequency array #ifdef _WIN32 std::vector<double> freqs(stateCount); #else double freqs[stateCount]; #endif // create an array containing site category weights #ifdef _WIN32 std::vector<double> weights(rateCategoryCount); #else double weights[rateCategoryCount]; #endif for (int eigenIndex=0; eigenIndex < eigenCount; eigenIndex++) { for (int i = 0; i < rateCategoryCount; i++) { weights[i] = gt_rand() / (double) GT_RAND_MAX; } beagleSetCategoryWeights(instance, eigenIndex, &weights[0]); } double* eval; if (!eigencomplex) eval = (double*)malloc(sizeof(double)*stateCount); else eval = (double*)malloc(sizeof(double)*stateCount*2); double* evec = (double*)malloc(sizeof(double)*stateCount*stateCount); double* ivec = (double*)malloc(sizeof(double)*stateCount*stateCount); for (int eigenIndex=0; eigenIndex < eigenCount; eigenIndex++) { if (!eigencomplex && ((stateCount & (stateCount-1)) == 0)) { for (int i=0; i<stateCount; i++) { freqs[i] = 1.0 / stateCount; } // an eigen decomposition for the general state-space JC69 model // If stateCount = 2^n is a power-of-two, then Sylvester matrix H_n describes // the eigendecomposition of the infinitesimal rate matrix double* Hn = evec; Hn[0*stateCount+0] = 1.0; Hn[0*stateCount+1] = 1.0; Hn[1*stateCount+0] = 1.0; Hn[1*stateCount+1] = -1.0; // H_1 for (int k=2; k < stateCount; k <<= 1) { // H_n = H_1 (Kronecker product) H_{n-1} for (int i=0; i<k; i++) { for (int j=i; j<k; j++) { double Hijold = Hn[i*stateCount + j]; Hn[i *stateCount + j + k] = Hijold; Hn[(i+k)*stateCount + j ] = Hijold; Hn[(i+k)*stateCount + j + k] = -Hijold; Hn[j *stateCount + i + k] = Hn[i *stateCount + j + k]; Hn[(j+k)*stateCount + i ] = Hn[(i+k)*stateCount + j ]; Hn[(j+k)*stateCount + i + k] = Hn[(i+k)*stateCount + j + k]; } } } // Since evec is Hadamard, ivec = (evec)^t / stateCount; for (int i=0; i<stateCount; i++) { for (int j=i; j<stateCount; j++) { ivec[i*stateCount+j] = evec[j*stateCount+i] / stateCount; ivec[j*stateCount+i] = ivec[i*stateCount+j]; // Symmetric } } eval[0] = 0.0; for (int i=1; i<stateCount; i++) { eval[i] = -stateCount / (stateCount - 1.0); } } else if (!eigencomplex) { for (int i=0; i<stateCount; i++) { freqs[i] = gt_rand() / (double) GT_RAND_MAX; } double** qmat=New2DArray<double>(stateCount, stateCount); double* relNucRates = new double[(stateCount * stateCount - stateCount) / 2]; int rnum=0; for(int i=0;i<stateCount;i++){ for(int j=i+1;j<stateCount;j++){ relNucRates[rnum] = gt_rand() / (double) GT_RAND_MAX; qmat[i][j]=relNucRates[rnum] * freqs[j]; qmat[j][i]=relNucRates[rnum] * freqs[i]; rnum++; } } //set diags to sum rows to 0 double sum; for(int x=0;x<stateCount;x++){ sum=0.0; for(int y=0;y<stateCount;y++){ if(x!=y) sum+=qmat[x][y]; } qmat[x][x]=-sum; } double* eigvalsimag=new double[stateCount]; double** eigvecs=New2DArray<double>(stateCount, stateCount);//eigenvecs double** teigvecs=New2DArray<double>(stateCount, stateCount);//temp eigenvecs double** inveigvecs=New2DArray<double>(stateCount, stateCount);//inv eigenvecs int* iwork=new int[stateCount]; double* work=new double[stateCount]; EigenRealGeneral(stateCount, qmat, eval, eigvalsimag, eigvecs, iwork, work); memcpy(*teigvecs, *eigvecs, stateCount*stateCount*sizeof(double)); InvertMatrix(teigvecs, stateCount, work, iwork, inveigvecs); for(int x=0;x<stateCount;x++){ for(int y=0;y<stateCount;y++){ evec[x * stateCount + y] = eigvecs[x][y]; if (ievectrans) ivec[x * stateCount + y] = inveigvecs[y][x]; else ivec[x * stateCount + y] = inveigvecs[x][y]; } } Delete2DArray(qmat); delete relNucRates; delete eigvalsimag; Delete2DArray(eigvecs); Delete2DArray(teigvecs); Delete2DArray(inveigvecs); delete iwork; delete work; } else if (eigencomplex && stateCount==4 && eigenCount==1) { // create base frequency array double temp_freqs[4] = { 0.25, 0.25, 0.25, 0.25 }; // an eigen decomposition for the 4-state 1-step circulant infinitesimal generator double temp_evec[4 * 4] = { -0.5, 0.6906786606674509, 0.15153543380548623, 0.5, 0.5, -0.15153543380548576, 0.6906786606674498, 0.5, -0.5, -0.6906786606674498, -0.15153543380548617, 0.5, 0.5, 0.15153543380548554, -0.6906786606674503, 0.5 }; double temp_ivec[4 * 4] = { -0.5, 0.5, -0.5, 0.5, 0.6906786606674505, -0.15153543380548617, -0.6906786606674507, 0.15153543380548645, 0.15153543380548568, 0.6906786606674509, -0.15153543380548584, -0.6906786606674509, 0.5, 0.5, 0.5, 0.5 }; double temp_eval[8] = { -2.0, -1.0, -1.0, 0, 0, 1, -1, 0 }; for(int x=0;x<stateCount;x++){ freqs[x] = temp_freqs[x]; eval[x] = temp_eval[x]; eval[x+stateCount] = temp_eval[x+stateCount]; for(int y=0;y<stateCount;y++){ evec[x * stateCount + y] = temp_evec[x * stateCount + y]; if (ievectrans) ivec[x * stateCount + y] = temp_ivec[x + y * stateCount]; else ivec[x * stateCount + y] = temp_ivec[x * stateCount + y]; } } } else { abort("should not be here"); } beagleSetStateFrequencies(instance, eigenIndex, &freqs[0]); if (!setmatrix) { // set the Eigen decomposition beagleSetEigenDecomposition(instance, eigenIndex, &evec[0], &ivec[0], &eval[0]); } } free(eval); free(evec); free(ivec); // a list of indices and edge lengths int* edgeIndices = new int[edgeCount*eigenCount]; int* edgeIndicesD1 = new int[edgeCount*eigenCount]; int* edgeIndicesD2 = new int[edgeCount*eigenCount]; for(int i=0; i<edgeCount*eigenCount; i++) { edgeIndices[i]=i; edgeIndicesD1[i]=(edgeCount*eigenCount)+i; edgeIndicesD2[i]=2*(edgeCount*eigenCount)+i; } double* edgeLengths = new double[edgeCount]; for(int i=0; i<edgeCount; i++) { edgeLengths[i]=gt_rand() / (double) GT_RAND_MAX; } // create a list of partial likelihood update operations // the order is [dest, destScaling, source1, matrix1, source2, matrix2] int* operations = new int[(internalCount)*BEAGLE_OP_COUNT*eigenCount]; int* scalingFactorsIndices = new int[(internalCount)*eigenCount]; // internal nodes for(int i=0; i<internalCount*eigenCount; i++){ operations[BEAGLE_OP_COUNT*i+0] = ntaxa+i; operations[BEAGLE_OP_COUNT*i+1] = (dynamicScaling ? i : BEAGLE_OP_NONE); operations[BEAGLE_OP_COUNT*i+2] = (dynamicScaling ? i : BEAGLE_OP_NONE); int child1Index; if (((i % internalCount)*2) < ntaxa) child1Index = (i % internalCount)*2; else child1Index = i*2 - internalCount * (int)(i / internalCount); operations[BEAGLE_OP_COUNT*i+3] = child1Index; operations[BEAGLE_OP_COUNT*i+4] = child1Index; int child2Index; if (((i % internalCount)*2+1) < ntaxa) child2Index = (i % internalCount)*2+1; else child2Index = i*2+1 - internalCount * (int)(i / internalCount); operations[BEAGLE_OP_COUNT*i+5] = child2Index; operations[BEAGLE_OP_COUNT*i+6] = child2Index; scalingFactorsIndices[i] = i; // printf("i %d dest %d c1 %d c2 %d\n", i, ntaxa+i, child1Index, child2Index); if (autoScaling) scalingFactorsIndices[i] += ntaxa; } int* rootIndices = new int[eigenCount]; int* lastTipIndices = new int[eigenCount]; int* categoryWeightsIndices = new int[eigenCount]; int* stateFrequencyIndices = new int[eigenCount]; int* cumulativeScalingFactorIndices = new int[eigenCount]; for (int eigenIndex=0; eigenIndex < eigenCount; eigenIndex++) { rootIndices[eigenIndex] = ntaxa+(internalCount*(eigenIndex+1))-1;//ntaxa*2-2; lastTipIndices[eigenIndex] = ntaxa-1; categoryWeightsIndices[eigenIndex] = eigenIndex; stateFrequencyIndices[eigenIndex] = 0; cumulativeScalingFactorIndices[eigenIndex] = ((manualScaling || dynamicScaling) ? (scaleCount*eigenCount-1)-eigenCount+eigenIndex+1 : BEAGLE_OP_NONE); if (dynamicScaling) beagleResetScaleFactors(instance, cumulativeScalingFactorIndices[eigenIndex]); } // start timing! struct timeval time1, time2, time3, time4, time5; double bestTimeUpdateTransitionMatrices, bestTimeUpdatePartials, bestTimeAccumulateScaleFactors, bestTimeCalculateRootLogLikelihoods, bestTimeTotal; double logL = 0.0; double deriv1 = 0.0; double deriv2 = 0.0; double previousLogL = 0.0; double previousDeriv1 = 0.0; double previousDeriv2 = 0.0; for (int i=0; i<nreps; i++){ if (manualScaling && (!(i % rescaleFrequency) || !((i-1) % rescaleFrequency))) { for(int j=0; j<internalCount*eigenCount; j++){ operations[BEAGLE_OP_COUNT*j+1] = (((manualScaling && !(i % rescaleFrequency))) ? j : BEAGLE_OP_NONE); operations[BEAGLE_OP_COUNT*j+2] = (((manualScaling && (i % rescaleFrequency))) ? j : BEAGLE_OP_NONE); } } gettimeofday(&time1,NULL); for (int eigenIndex=0; eigenIndex < eigenCount; eigenIndex++) { if (!setmatrix) { // tell BEAGLE to populate the transition matrices for the above edge lengths beagleUpdateTransitionMatrices(instance, // instance eigenIndex, // eigenIndex &edgeIndices[eigenIndex*edgeCount], // probabilityIndices (calcderivs ? &edgeIndicesD1[eigenIndex*edgeCount] : NULL), // firstDerivativeIndices (calcderivs ? &edgeIndicesD2[eigenIndex*edgeCount] : NULL), // secondDerivativeIndices edgeLengths, // edgeLengths edgeCount); // count } else { double* inMatrix = new double[stateCount*stateCount*rateCategoryCount]; for (int matrixIndex=0; matrixIndex < edgeCount; matrixIndex++) { for(int z=0;z<rateCategoryCount;z++){ for(int x=0;x<stateCount;x++){ for(int y=0;y<stateCount;y++){ inMatrix[z*stateCount*stateCount + x*stateCount + y] = gt_rand() / (double) GT_RAND_MAX; } } } beagleSetTransitionMatrix(instance, edgeIndices[eigenIndex*edgeCount + matrixIndex], inMatrix, 1); if (calcderivs) { beagleSetTransitionMatrix(instance, edgeIndicesD1[eigenIndex*edgeCount + matrixIndex], inMatrix, 0); beagleSetTransitionMatrix(instance, edgeIndicesD2[eigenIndex*edgeCount + matrixIndex], inMatrix, 0); } } } } gettimeofday(&time2, NULL); // update the partials beagleUpdatePartials( instance, // instance (BeagleOperation*)operations, // eigenIndex internalCount*eigenCount, // operationCount (dynamicScaling ? internalCount : BEAGLE_OP_NONE)); // cumulative scaling index gettimeofday(&time3, NULL); int scalingFactorsCount = internalCount; for (int eigenIndex=0; eigenIndex < eigenCount; eigenIndex++) { if (manualScaling && !(i % rescaleFrequency)) { beagleResetScaleFactors(instance, cumulativeScalingFactorIndices[eigenIndex]); beagleAccumulateScaleFactors(instance, &scalingFactorsIndices[eigenIndex*internalCount], scalingFactorsCount, cumulativeScalingFactorIndices[eigenIndex]); } else if (autoScaling) { beagleAccumulateScaleFactors(instance, &scalingFactorsIndices[eigenIndex*internalCount], scalingFactorsCount, BEAGLE_OP_NONE); } } gettimeofday(&time4, NULL); // calculate the site likelihoods at the root node if (!unrooted) { beagleCalculateRootLogLikelihoods(instance, // instance rootIndices,// bufferIndices categoryWeightsIndices, // weights stateFrequencyIndices, // stateFrequencies cumulativeScalingFactorIndices, eigenCount, // count &logL); // outLogLikelihoods } else { // calculate the site likelihoods at the root node beagleCalculateEdgeLogLikelihoods(instance, // instance rootIndices,// bufferIndices lastTipIndices, lastTipIndices, (calcderivs ? edgeIndicesD1 : NULL), (calcderivs ? edgeIndicesD2 : NULL), categoryWeightsIndices, // weights stateFrequencyIndices, // stateFrequencies cumulativeScalingFactorIndices, eigenCount, // count &logL, // outLogLikelihood (calcderivs ? &deriv1 : NULL), (calcderivs ? &deriv2 : NULL)); } // end timing! gettimeofday(&time5,NULL); if (i == 0 || getTimeDiff(time1, time2) < bestTimeUpdateTransitionMatrices) bestTimeUpdateTransitionMatrices = getTimeDiff(time1, time2); if (i == 0 || getTimeDiff(time2, time3) < bestTimeUpdatePartials) bestTimeUpdatePartials = getTimeDiff(time2, time3); if (i == 0 || getTimeDiff(time3, time4) < bestTimeAccumulateScaleFactors) bestTimeAccumulateScaleFactors = getTimeDiff(time3, time4); if (i == 0 || getTimeDiff(time4, time5) < bestTimeUpdateTransitionMatrices) bestTimeCalculateRootLogLikelihoods = getTimeDiff(time4, time5); if (i == 0 || getTimeDiff(time1, time5) < bestTimeTotal) bestTimeTotal = getTimeDiff(time1, time5); if (!(logL - logL == 0.0)) abort("error: invalid lnL"); if (i > 0 && abs(logL - previousLogL) > MAX_DIFF) abort("error: large lnL difference between reps"); if (calcderivs) { if (!(deriv1 - deriv1 == 0.0) || !(deriv2 - deriv2 == 0.0)) abort("error: invalid deriv"); if (i > 0 && ((abs(deriv1 - previousDeriv1) > MAX_DIFF) || (abs(deriv2 - previousDeriv2) > MAX_DIFF)) ) abort("error: large deriv difference between reps"); } previousLogL = logL; previousDeriv1 = deriv1; previousDeriv2 = deriv2; } if (resource == 0) { cpuTimeUpdateTransitionMatrices = bestTimeUpdateTransitionMatrices; cpuTimeUpdatePartials = bestTimeUpdatePartials; cpuTimeAccumulateScaleFactors = bestTimeAccumulateScaleFactors; cpuTimeCalculateRootLogLikelihoods = bestTimeCalculateRootLogLikelihoods; cpuTimeTotal = bestTimeTotal; } if (!calcderivs) fprintf(stdout, "logL = %.5f \n", logL); else fprintf(stdout, "logL = %.5f d1 = %.5f d2 = %.5f\n", logL, deriv1, deriv2); std::cout.setf(std::ios::showpoint); std::cout.setf(std::ios::floatfield, std::ios::fixed); int timePrecision = 6; int speedupPrecision = 2; int percentPrecision = 2; std::cout << "best run: "; printTiming(bestTimeTotal, timePrecision, resource, cpuTimeTotal, speedupPrecision, 0, 0, 0); if (fullTiming) { std::cout << " transMats: "; printTiming(bestTimeUpdateTransitionMatrices, timePrecision, resource, cpuTimeUpdateTransitionMatrices, speedupPrecision, 1, bestTimeTotal, percentPrecision); std::cout << " partials: "; printTiming(bestTimeUpdatePartials, timePrecision, resource, cpuTimeUpdatePartials, speedupPrecision, 1, bestTimeTotal, percentPrecision); if (manualScaling || autoScaling) { std::cout << " accScalers: "; printTiming(bestTimeAccumulateScaleFactors, timePrecision, resource, cpuTimeAccumulateScaleFactors, speedupPrecision, 1, bestTimeTotal, percentPrecision); } std::cout << " rootLnL: "; printTiming(bestTimeCalculateRootLogLikelihoods, timePrecision, resource, cpuTimeCalculateRootLogLikelihoods, speedupPrecision, 1, bestTimeTotal, percentPrecision); } std::cout << "\n"; beagleFinalizeInstance(instance); }
double calc_ln_likelihood() { ////////////////////////////////////////////////////////////////////////////// // Setup and initialze Beagle std::vector<PhylogeneticNode *> nodes; this->seed_node_->get_nodes_postorder(nodes); std::vector<PhylogeneticNode *> leaf_nodes; this->seed_node_->get_leaf_nodes(leaf_nodes); std::vector<PhylogeneticNode *> internal_nodes; this->seed_node_->get_internal_nodes_postorder(internal_nodes, true); int num_sites = leaf_nodes[0]->get_state_vector_len(); int num_nodes = nodes.size(); int num_tip_nodes = leaf_nodes.size(); int num_int_nodes = internal_nodes.size() ; int num_partials = num_nodes; BeagleInstanceDetails * return_info = new BeagleInstanceDetails(); int beagle_instance = beagleCreateInstance( num_tip_nodes, // Number of tip data elements (input) num_partials, // Number of partials buffers to create (input) -- internal node count num_tip_nodes, // Number of compact state representation buffers to create -- for use with setTipStates (input) 4, // Number of states in the continuous-time Markov chain (input) -- DNA num_sites, // Number of site patterns to be handled by the instance (input) -- not compressed in this case 1, // Number of eigen-decomposition buffers to allocate (input) num_nodes, // Number of transition matrix buffers (input) -- one per edge 1, // Number of rate categories 0, // Number of scaling buffers -- can be zero if scaling is not needed NULL, // List of potential resource on which this instance is allowed (input, NULL implies no restriction 0, // Length of resourceList list (input) -- not needed to use the default hardware config 0, // Bit-flags indicating preferred implementation charactertistics, see BeagleFlags (input) 0, // Bit-flags indicating required implementation characteristics, see BeagleFlags (input) return_info ); if (beagle_instance < 0) { std::cerr << "\n\n***ERROR*** Failed to obtain BEAGLE instance\n" << std::endl; exit(1); } int ret_code = 0; for (int i; i < num_tip_nodes; ++i) { // ret_code = beagleSetTipPartials( // beagle_instance, // instance // leaf_nodes[i]->get_index(), // bufferIndex // leaf_nodes[i]->get_partials_data() // inPartials // ); ret_code = beagleSetTipStates( beagle_instance, leaf_nodes[i]->get_index(), leaf_nodes[i]->get_state_vector_data() ); if (ret_code != 0) { std::cerr << "\n\n***ERROR*** Failed to set tip data\n" << std::endl; exit(1); } } // let all sites have equal weight std::vector<double> pattern_weights( num_sites, 1 ); beagleSetPatternWeights(beagle_instance, pattern_weights.data()); // create array of state background frequencies double freqs[4] = { 0.25, 0.25, 0.25, 0.25 }; beagleSetStateFrequencies(beagle_instance, 0, freqs); // create an array containing site category weights and rates const double weights[1] = { 1.0 }; const double rates[1] = { 1.0 }; beagleSetCategoryWeights(beagle_instance, 0, weights); beagleSetCategoryRates(beagle_instance, rates); double evec[4 * 4] = { 1.0, 2.0, 0.0, 0.5, 1.0, -2.0, 0.5, 0.0, 1.0, 2.0, 0.0, -0.5, 1.0, -2.0, -0.5, 0.0 }; // JC69 model inverse eigenvector matrix double ivec[4 * 4] = { 0.25, 0.25, 0.25, 0.25, 0.125, -0.125, 0.125, -0.125, 0.0, 1.0, 0.0, -1.0, 1.0, 0.0, -1.0, 0.0 }; // JC69 model eigenvalues double eval[4] = { 0.0, -1.3333333333333333, -1.3333333333333333, -1.3333333333333333 }; ret_code = beagleSetEigenDecomposition( beagle_instance, // instance 0, // eigenIndex, (const double *)evec, // inEigenVectors, (const double *)ivec, // inInverseEigenVectors, eval); // inEigenValues if (ret_code != 0) { std::cerr << "\n\n***ERROR*** Failed to set eigen decomposition\n" << std::endl; exit(1); } ////////////////////////////////////////////////////////////////////////////// // Calculate log-likelihood // a list of indices and edge lengths // these get used to tell beagle which edge length goes with which node std::vector<int> node_indices; std::vector<double> edge_lens; for (auto &nd : nodes) { node_indices.push_back(nd->get_index()); edge_lens.push_back(nd->get_edge_len()); } // tell BEAGLE to populate the transition matrices for the above edge lengthss beagleUpdateTransitionMatrices(beagle_instance, // instance 0, // eigenIndex node_indices.data(), // probabilityIndices NULL, // firstDerivativeIndices NULL, // secondDervativeIndices edge_lens.data(), // edgeLengths node_indices.size()); // count // create a list of partial likelihood update operations // the order is [dest, sourceScaling, destScaling, source1, matrix1, source2, matrix2] // these operations say: first peel node 0 and 1 to calculate the per-site partial likelihoods, and store them // in buffer 3. Then peel node 2 and buffer 3 and store the per-site partial likelihoods in buffer 4. // BeagleOperation operations[2] = { // {3, BEAGLE_OP_NONE, BEAGLE_OP_NONE, 0, 0, 1, 1}, // {4, BEAGLE_OP_NONE, BEAGLE_OP_NONE, 2, 2, 3, 3} // }; std::vector<BeagleOperation> beagle_operations; int ch1_idx = 0; int ch2_idx = 0; for (auto &nd : internal_nodes) { ch1_idx = nd->get_child_node_index(0); ch2_idx = nd->get_child_node_index(1); std::cerr << nd->get_index() << ": " << ch1_idx << ", " << ch2_idx << std::endl; beagle_operations.push_back( {nd->get_index(), BEAGLE_OP_NONE, BEAGLE_OP_NONE, ch1_idx, ch1_idx, ch2_idx, ch2_idx} ); } // this invokes all the math to carry out the likelihood calculation beagleUpdatePartials( beagle_instance, // instance beagle_operations.data(), // eigenIndex beagle_operations.size(), // operationCount BEAGLE_OP_NONE); // cumulative scale index // for (auto &nd : nodes) { // std::cerr << nd->get_index() << ":"; // for (unsigned int i = 0; i < 4; ++i) { // std::cerr << " " << nd->get_partial(i); // } // std::cerr << std::endl; // } double logL = 0; int root_index[1] = {this->seed_node_->get_index()}; int category_weight_index[1] = {0}; int state_freq_index[1] = {0}; int cumulative_scale_index[1] = {BEAGLE_OP_NONE}; // calculate the site likelihoods at the root node // this integrates the per-site root partial likelihoods across sites, background state frequencies, and rate categories // results in a single log likelihood, output here into logL beagleCalculateRootLogLikelihoods(beagle_instance, // instance root_index,// bufferIndices category_weight_index, // weights state_freq_index, // stateFrequencies cumulative_scale_index, // scaleBuffer to use 1, // count &logL); // outLogLikelihoods return logL; }