Example #1
0
Polyhedron *
kaleido(char *sym, int need_coordinates, int need_edgelist, int need_approx,
	int just_list)
{
    Polyhedron *P;
/*
 * Allocate a Polyhedron structure P.
 */
    if (!(P = polyalloc()))
	return 0;
/*
 * Unpack input symbol into P.
 */
    if (!unpacksym(sym, P))
	return 0;
/*
 * Find Mebius triangle, its density and Euler characteristic.
 */
    if (!moebius(P))
	return 0;
/*
 * Decompose Schwarz triangle.
 */
    if (!decompose(P))
	return 0;
/*
 * Find the names of the polyhedron and its dual.
 */
    if (!guessname(P))
	return 0;
    if (just_list)
	return P;
/*
 * Solve Fundamental triangles, optionally printing approximations.
 */
    if (!newton(P,need_approx))
	return 0;
/*
 * Deal with exceptional polyhedra.
 */
    if (!exceptions(P))
	return 0;
/*
 * Count edges and faces, update density and characteristic if needed.
 */
    if (!count(P))
	return 0;
/*
 * Generate printable vertex configuration.
 */
    if (!configuration(P))
	return 0;
/*
 * Compute coordinates.
 */
    if (!need_coordinates && !need_edgelist)
	return P;
    if (!vertices(P))
	return 0;
    if (!faces (P))
	return 0;
/*
 * Compute edgelist.
 */
    if (!need_edgelist)
	return P;
    if (!edgelist(P))
	return 0;
    return P;
}
Example #2
0
int main(int argc, char* argv[])
{
    //set scale, edges per node, and maximum number of test search keys
    int scale = 0;
    int edgefactor = 0;
    unsigned int NBFS = 64;
    unsigned int maximumvertex = 0;
    int validateFlag = INT_MIN;

    if (argc == 4)
    {
        scale = std::atoi(argv[1]);
        if (scale < 4 || scale > 26)
        {
            std::cout << "Scale must be between 4 and 26" << std::endl;
            return -1;
        }
        edgefactor = std::atoi(argv[2]);
        if (edgefactor != 2 && edgefactor != 16)
        {
            std::cout << "Edgefactor must be 2 or 16" << std::endl;
            return -1;
        }
        if (std::atoi(argv[3]) != 0)
        {
            validateFlag = 1;
        }
    }
    else if (argc != 1)
    {
        std::cout<< "please enter scale, edgefactor, validate" << std::endl;
    }
    else
    {

        std::cout << "Enter problem scale" << std::endl;
        std::cout << "Scale: ";

//get user input for scale and edgefactor
        while(true)
        {
            getint(scale);
            if (scale > 2 && scale < 27)
            {
                break;
            }
            std::cout << "Number out of bounds" << std::endl;
            std::cout << std::endl;
        }

        std::cout << "Enter edge factor" << std::endl;
        std::cout << "Recommended: 2 (debug), 16" << std::endl;
        std::cout << "Edge Factor: ";

        while(true)
        {
            getint(edgefactor);
            if (edgefactor == 16 || edgefactor == 2)
            {
                break;
            }
            std::cout << "Just put in 16" << std::endl;
        }

        std::cout << "Run validate function? 1=yes, 0=no" << std::endl;

        while(true)
        {
            getint(validateFlag);
            if (validateFlag == 0)
            {
                std::cout << "Not running validate function!" << std::endl;
                break;
            }
            else if (validateFlag == 1)
            {
                break;
            }
            std::cout << "Enter 1 or 0" << std::endl;
        }
    }



//vector of triplets (row, col, val) to pass to kronecker generator
    std::vector<EigenTriplet> edgelist(0);

    std::cout << "calling kronecker generator" << std::endl;

    kronecker(scale, edgefactor, edgelist);
    std::cout << "done with kronecker" << std::endl;


//add transposed edgelist values to end of edgelist vector
//plays nicer with Eigen's setFromTriplets function
//otherwise Eigen can't make symmetric matrices well
    edgelist.reserve(2*edgelist.size());
    unsigned int edgeListOriginalSize = edgelist.size();
    for (unsigned int i = 0; i < edgeListOriginalSize; i++)
    {
        edgelist.push_back(EigenTriplet(edgelist.at(i).col(),edgelist.at(i).row(),1));
    }



//create container for adjacency matrix
    Eigen::SparseMatrix<int> EdgeMatrix(0,0);

    std::cout << "transform edgelist into sparse adjacency matrix" << std::endl;


//call kernel 1 to fill EdgeMatrix with data from edgelist
    sparseMatrixFromEdgelist(edgelist, EdgeMatrix, maximumvertex);



    std::vector<int> search_key;
    createSearchKey(EdgeMatrix.rows(), NBFS, search_key, EdgeMatrix);

    if (search_key.size() < NBFS)
    {
        NBFS = search_key.size();
    }



//create parent array and fill with negative 1
    std::vector<int> parent(EdgeMatrix.cols(),-1);

//calculate number of edges
//edgelist = original + transposed, so just sum along one column
    std::vector<int> edgehistogram(EdgeMatrix.cols(),0);
    for (unsigned int i = 0; i < edgelist.size(); i++)
    {
        edgehistogram.at(edgelist.at(i).col()) += 1;
    }


    std::cout << "calling BFS algorithm" << std::endl;

//fill parent array by doing BFS on edgematrix starting at search_key(k)
//calculate number of edges in graph connected to search_key
//occasionally have a small graph subsection with few edges that could falsely increase performance

    std::vector<double> numberedges(NBFS,0);
    std::vector<double> searchtime(NBFS,0);
    std::vector<double> TEPS(NBFS,0);

    //std::cout << EdgeMatrix << std::endl;

#ifdef VALGRIND_INCLUDED
    CALLGRIND_START_INSTRUMENTATION;
#endif
    for (unsigned int k = 0; k < NBFS; k++)
    {

        std::chrono::time_point<std::chrono::high_resolution_clock> timerstart, timerend;

        //search and validate results
        std::cout << "starting BFS on search key " << k << ": " << search_key.at(k) << std::endl;
        timerstart = std::chrono::high_resolution_clock::now();




        //bfsTopDownSerial(EdgeMatrix, search_key.at(k), parent, maximumvertex);
        //bfsTopDownOMP(EdgeMatrix, search_key.at(k), parent);
        bfsHybridOMP(EdgeMatrix, search_key.at(k), parent);

        timerend = std::chrono::high_resolution_clock::now();

        searchtime.at(k) = std::chrono::duration_cast<std::chrono::nanoseconds>(timerend-timerstart).count();


        //find number of edges from parent array

        for (unsigned int i = 0; i < parent.size(); i++)
        {
            if (parent.at(i) >= 0)
            {
                numberedges.at(k) += edgehistogram.at(i);
            }
        }
        numberedges.at(k) /= 2.0;
        TEPS.at(k) = numberedges.at(k)/(searchtime.at(k));

        if (validateFlag == 1)
        {
            std::cout << "Checking Search Key " << k << ": " << search_key.at(k) << std::endl;
            int validatecode = validateParentArray(parent,edgelist,search_key.at(k), maximumvertex);
            if (validatecode != 1)
            {
                std::cout << "validation failed on search key " << search_key.at(k) << std::endl;
                return validatecode;
            }

        }

        //clear parent array for next search
        //if you want to save it write it to file first
        std::fill(parent.begin(),parent.end(),-1);

    }

#ifdef VALGRIND_INCLUDED
    CALLGRIND_STOP_INSTRUMENTATION;
    CALLGRIND_DUMP_STATS;
#endif




//std::cout << EdgeMatrix << std::endl;

    std::cout << "time, number edges, TEPS" << std::endl;
    for (unsigned int i = 0; i < numberedges.size(); i++)
    {
        std::cout << searchtime.at(i) << " " << numberedges.at(i) << " " << TEPS.at(i) << "\n";
    }
    std::cout << std::endl;

    std::ofstream datafile;
    datafile.open("GTEPS.txt", std::ofstream::app);
#define average(vector) (std::accumulate(vector.begin(),vector.end(),0.0)/(double)vector.size())
    datafile << scale << " " << average(searchtime) << " " << average(numberedges) << " " << average(TEPS) << "\n";
    datafile.close();



    return 0;
}