Пример #1
0
/**
 * Controller helper routine.
 *
 * Wait for the next running slave to finish a task.  Note that if no
 * slaves are currently processing tasks, this routine will block forever!
 */
int ctrlWaitForSlave() {
    long result;
    MPI_Status status;
    MPI_Recv(&result, 1, MPI_LONG, MPI_ANY_SOURCE, TAG_RESULT, MPI_COMM_WORLD,
        &status);
    nRunningSlaves--;

    int slave = status.MPI_SOURCE;
    ctrlLogStamp() << "Task completed by slave " << slave << "." << std::endl;

    char triLabel[MAX_TRI_LABEL_LEN + 1];

    if (result == RESULT_OK || result == RESULT_HAS_NEW) {
        if (result == RESULT_HAS_NEW) {
            // The original packet label comes through first so we can
            // write it to the log.  It will come through again shortly
            // as part of the set of equivalent triangulations.
            MPI_Recv(triLabel, MAX_TRI_LABEL_LEN + 1, MPI_CHAR, slave,
                TAG_RESULT_DATA, MPI_COMM_WORLD, &status);
            ctrlLogStamp() << "WARNING: Has unseen equivalent: " << triLabel
                << std::endl;
            nHasNew++;
        }

        equivs.clear();

        NPacket* p;
        NTriangulation* tri;
        while (1) {
            MPI_Recv(triLabel, MAX_TRI_LABEL_LEN + 1, MPI_CHAR, slave,
                TAG_RESULT_DATA, MPI_COMM_WORLD, &status);
            if (*triLabel == 0)
                break;

            p = tree->findPacketLabel(triLabel);
            if (! p) {
                ctrlLogStamp() << "ERROR: Returned equivalent [" << triLabel
                    << "] not found." << std::endl;
                hasError = true;
            } else {
                tri = dynamic_cast<NTriangulation*>(p);
                if (! tri) {
                    ctrlLogStamp() << "ERROR: Returned equivalent [" << triLabel
                        << "] is not a triangulation!" << std::endl;
                    hasError = true;
                } else
                    equivs.insert(tri);
            }
        }
        ctrlLogStamp() << "Resulting set contains "
            << equivs.size() << " equivalent(s)." << std::endl;

        // In equivs we now have a list of all triangulations
        // equivalent to orig.

        // Is this an equivalence class we're already seen?
        TriSet::iterator tit;
        ClassMap::iterator cit, cit2;
        for (tit = equivs.begin(); tit != equivs.end(); tit++) {
            cit = eClass.find(*tit);
            if (cit != eClass.end())
                break;
        }
        if (tit != equivs.end()) {
            // We found an equivalence class.  Insert everything we
            // haven't seen yet, and merge the classes of everything
            // we have.
            int c, cOld;
            c = cit->second;
            for (tit = equivs.begin(); tit != equivs.end(); tit++) {
                cit = eClass.find(*tit);
                if (cit == eClass.end())
                    eClass.insert(std::make_pair(*tit, c));
                else if (cit->second != c) {
                    // Merge the two equivalence classes.
                    cOld = cit->second;
                    for (cit = eClass.begin(); cit != eClass.end(); cit++)
                        if (cit->second == cOld)
                            cit->second = c;
                    nClasses--;
                }
            }
        } else {
            // No such equivalence class.  Insert everything.
            int c = nextClass++;
            for (tit = equivs.begin(); tit != equivs.end(); tit++)
                eClass.insert(std::make_pair(*tit, c));
            nClasses++;
        }
    } else if (result == RESULT_NON_MINIMAL) {
        MPI_Recv(triLabel, MAX_TRI_LABEL_LEN + 1, MPI_CHAR, slave,
            TAG_RESULT_DATA, MPI_COMM_WORLD, &status);
        ctrlLogStamp() << "Non-minimal triangulation: " << triLabel
            << std::endl;

        nNonMin++;
    } else if (result == RESULT_ERR) {
        char errMsg[MAX_ERR_MSG_LEN + 1];
        MPI_Recv(errMsg, MAX_ERR_MSG_LEN + 1, MPI_CHAR, slave,
            TAG_RESULT_DATA, MPI_COMM_WORLD, &status);

        ctrlLogStamp() << "ERROR: " << errMsg << std::endl;
        hasError = true;
    } else {
        ctrlLogStamp() << "ERROR: Unknown result code " << result
            << " received from slave." << std::endl;
        hasError = true;
    }

    return slave;
}
Пример #2
0
/**
 * Main routine for the controller.
 */
int mainController() {
    NTriangulation* t;

    // Start logging.
    logger.open(logFile);
    if (! logger) {
        fprintf(stderr, "Could not open %s for writing.\n", logFile);
        return 1;
    }

    // Do it.
    for (NPacket* p = tree; p; p = p->nextTreePacket())
        if (p->type() == PACKET_TRIANGULATION) {
            nTris++;
            ctrlFarmTri(static_cast<NTriangulation*>(p));
        }

    // Kill off any slaves that never started working, since there are no
    // tasks left to give them.
    if (nRunningSlaves < nSlaves)
        for (int i = nRunningSlaves; i < nSlaves; i++)
            ctrlStopSlave(i + 1);

    // Wait for remaining slaves to finish.
    while (nRunningSlaves > 0)
        ctrlFarmTri(0);

    // Done!
    ctrlLogStamp() << "All slaves finished." << std::endl;

    // Write the summary of results.
    if (nClasses) {
        printf("EQUIVALENCE CLASSES:\n\n");

        if (outFile) {
            newTree = new NContainer();
            newTree->setLabel("Equivalence Classes");
        }

        int classNum = 1;
        std::string className;
        NContainer* classCnt = 0;

        ClassMap::iterator cit, cit2;
        int c;
        for (cit = eClass.begin(); cit != eClass.end(); cit++)
            if (cit->second >= 0) {
                // The first triangulation of a new equivalence class.
                c = cit->second;

                std::ostringstream s;
                s << "Class " << classNum << " : " <<
                    cit->first->homology().str();
                className = s.str();
                classNum++;

                printf("%s\n\n", className.c_str());
                if (outFile) {
                    classCnt = new NContainer();
                    classCnt->setLabel(className);
                    newTree->insertChildLast(classCnt);
                }

                // Find the triangulations in this class, and erase the
                // class as we go.
                for (cit2 = cit; cit2 != eClass.end(); cit2++)
                    if (cit2->second == c) {
                        printf("    %s\n",
                            cit2->first->label().c_str());
                        if (outFile) {
                            t = new NTriangulation(*(cit2->first));
                            t->setLabel(cit2->first->label());
                            classCnt->insertChildLast(t);
                        }

                        cit2->second = -1;
                    }

                printf("\n");
            }
    }

    printf("Final statistics:\n");
    printf("    Triangulations read:            %ld\n", nTris);
    printf("    Equivalence classes:            %ld\n", nClasses);
    printf("    Non-minimal triangulations:     %ld\n", nNonMin);
    printf("    Triangulations with new equivs: %ld\n", nHasNew);

    // Are we saving results?
    if (outFile && newTree) {
        ctrlLogStamp() << "Saving results to " << outFile << "." << std::endl;
        newTree->save(outFile);
    } else
        ctrlLogStamp() << "Not saving results." << std::endl;

    // Clean up and exit.
    if (newTree)
        delete newTree;

    if (hasError) {
        ctrlLogStamp() << "ERROR: One or more errors occurred; "
            "read back through the log for details." << std::endl;
        printf("\nERROR: One or more errors occurred.\n");
        printf(  "       Please read through the log file %s for details.\n",
            logFile);
    } else
        ctrlLogStamp() << "All done." << std::endl;

    return 0;
}
Пример #3
0
void processTree() {
    TriSet::iterator tit;
    ClassMap::iterator cit, cit2;
    int c, cOld;
    NTriangulation* t;

    for (NPacket* p = tree; p; p = p->nextTreePacket())
        if (p->type() == PACKET_TRIANGULATION) {
            // A triangulation to process.
            t = static_cast<NTriangulation*>(p);
            fprintf(stderr, "Processing %s ...\n", t->label().c_str());
            nTris++;

            nonMin = false;
            orig = static_cast<NTriangulation*>(p);
            equivs.clear();
            equivs.insert(orig);

            tryMovesUp(orig, argUp);

            if (nonMin) {
                allNonMin.push_back(orig);
                nNonMin++;
                continue;
            }

            // In equivs we now have a list of all triangulations
            // equivalent to orig.

            // Is this an equivalence class we're already seen?
            for (tit = equivs.begin(); tit != equivs.end(); tit++) {
                cit = eClass.find(*tit);
                if (cit != eClass.end())
                    break;
            }
            if (tit != equivs.end()) {
                // We found an equivalence class.  Insert everything we
                // haven't seen yet, and merge the classes of everything
                // we have.
                c = cit->second;
                for (tit = equivs.begin(); tit != equivs.end(); tit++) {
                    cit = eClass.find(*tit);
                    if (cit == eClass.end())
                        eClass.insert(std::make_pair(*tit, c));
                    else if (cit->second != c) {
                        // Merge the two equivalence classes.
                        cOld = cit->second;
                        for (cit = eClass.begin(); cit != eClass.end(); cit++)
                            if (cit->second == cOld)
                                cit->second = c;
                        nClasses--;
                    }
                }
            } else {
                // No such equivalence class.  Insert everything.
                c = nextClass++;
                for (tit = equivs.begin(); tit != equivs.end(); tit++)
                    eClass.insert(std::make_pair(*tit, c));
                nClasses++;
            }
        }

    // Finished progress reporting.
    fprintf(stderr, "\n");

    // Write the summary of results.
    if (! allNonMin.empty()) {
        printf("NON-MINIMAL TRIANGULATIONS:\n\n");
        for (std::list<NTriangulation*>::const_iterator it = allNonMin.begin();
                it != allNonMin.end(); it++)
            printf("    %s\n", (*it)->label().c_str());
        printf("\n");
    }

    if (nClasses) {
        printf("EQUIVALENCE CLASSES:\n\n");

        if (outFile) {
            newTree = new NContainer();
            newTree->setLabel("Equivalence Classes");
        }

        int classNum = 1;
        std::string className;
        NContainer* classCnt = 0;

        for (cit = eClass.begin(); cit != eClass.end(); cit++)
            if (cit->second >= 0) {
                // The first triangulation of a new equivalence class.
                c = cit->second;

                std::ostringstream s;
                s << "Class " << classNum << " : " <<
                  cit->first->homology().str();
                className = s.str();
                classNum++;

                printf("%s\n\n", className.c_str());
                if (outFile) {
                    classCnt = new NContainer();
                    classCnt->setLabel(className);
                    newTree->insertChildLast(classCnt);
                }

                // Find the triangulations in this class, and erase the
                // class as we go.
                for (cit2 = cit; cit2 != eClass.end(); cit2++)
                    if (cit2->second == c) {
                        printf("    %s\n",
                               cit2->first->label().c_str());
                        if (outFile) {
                            t = new NTriangulation(*(cit2->first));
                            t->setLabel(cit2->first->label());
                            classCnt->insertChildLast(t);
                        }

                        cit2->second = -1;
                    }

                printf("\n");
            }
    }

    printf("Final statistics:\n");
    printf("    Triangulations read:        %ld\n", nTris);
    printf("    Equivalence classes:        %ld\n", nClasses);
    printf("    New triangulations:         %ld\n", nNew);
    printf("    Non-minimal triangulations: %ld\n", nNonMin);
}