Init commit: a bare implementation before parallelism
This commit is contained in:
+112
@@ -0,0 +1,112 @@
|
||||
/*!
|
||||
* \file main.cpp
|
||||
* \brief Main application file
|
||||
*
|
||||
* \author
|
||||
* Christos Choutouridis AEM:8997
|
||||
* <cchoutou@ece.auth.gr>
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <exception>
|
||||
|
||||
#include <utils.h>
|
||||
#include <config.h>
|
||||
|
||||
// Global session data
|
||||
session_t session;
|
||||
|
||||
/*!
|
||||
* A small command line argument parser
|
||||
* \return The status of the operation
|
||||
*/
|
||||
bool get_options(int argc, char* argv[]){
|
||||
bool status =true;
|
||||
|
||||
// iterate over the passed arguments
|
||||
for (int i=1 ; i<argc ; ++i) {
|
||||
std::string arg(argv[i]); // get current argument
|
||||
|
||||
if (arg == "-i" || arg == "--input") {
|
||||
session.inputMatrix = InputMatrix::MTX;
|
||||
if (i+1 < argc)
|
||||
session.mtxFile = std::ifstream(argv[++i]);
|
||||
else
|
||||
status = false;
|
||||
}
|
||||
else if (arg == "-g" || arg == "--generate")
|
||||
session.inputMatrix = InputMatrix::GENERATE;
|
||||
else if (arg == "-s" || arg == "--size")
|
||||
session.size = (i+1 < argc) ? std::atoi(argv[++i]) : session.size;
|
||||
else if (arg == "-p" || arg == "--probability")
|
||||
session.probability = (i+1 < argc) ? std::atof(argv[++i]) : session.probability;
|
||||
else if (arg == "--print") {
|
||||
session.print = true;
|
||||
session.print_size = (i+1 < argc) ? std::atoi(argv[++i]) : session.print_size;
|
||||
}
|
||||
else if (arg == "--make_symmetric")
|
||||
session.makeSymmetric = true;
|
||||
else if (arg == "-t" || arg == "--timing")
|
||||
session.timing = true;
|
||||
else if (arg == "-h" || arg == "--help") {
|
||||
std::cout << "Help message\n";
|
||||
exit(0);
|
||||
}
|
||||
else {
|
||||
std::cout << "Error message\n";
|
||||
status = false;
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char* argv[]) try {
|
||||
Timing timer;
|
||||
matrix A;
|
||||
|
||||
// try to read command line
|
||||
if (!get_options(argc, argv))
|
||||
exit(1);
|
||||
|
||||
// get or generate matrix
|
||||
if (session.inputMatrix == InputMatrix::GENERATE) {
|
||||
std::cout << "Initialize matrix with size: " << session.size << " and probability: " << session.probability << '\n';
|
||||
timer.start();
|
||||
A.size(session.size);
|
||||
init_ER_graph(A, session.probability);
|
||||
timer.stop();
|
||||
if (session.timing) timer.print_dt();
|
||||
}
|
||||
else {
|
||||
std::cout << "Read matrix from file\n";
|
||||
timer.start();
|
||||
if (session.makeSymmetric && !Mtx::is_triangular<matrix::indexType> (session.mtxFile))
|
||||
throw std::runtime_error("Error: Matrix is not strictly upper or lower");
|
||||
if (!Mtx::load (A, session.mtxFile)) {
|
||||
throw std::runtime_error("Error: fail to load matrix");
|
||||
}
|
||||
timer.stop();
|
||||
std::cout << "Matrix size: " << A.size() << " and capacity: " << A.capacity() <<'\n';
|
||||
if (session.timing) timer.print_dt();
|
||||
}
|
||||
|
||||
if (session.print) {
|
||||
std::cout << "Array A:\n";
|
||||
print_ER_graph (A);
|
||||
}
|
||||
|
||||
std::cout << "count triangles\n";
|
||||
timer.start();
|
||||
std::cout << "There are " << triang_count(A) << " triangles\n";
|
||||
timer.stop();
|
||||
if (session.timing) timer.print_dt();
|
||||
|
||||
return 0;
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
//we probably pollute the user's screen. Comment `cerr << ...` if you don't like it.
|
||||
std::cerr << e.what() << '\n';
|
||||
exit(1);
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*!
|
||||
* \file utils.cpp
|
||||
* \brief Utilities to handle matrix files, chrono, etc...
|
||||
*
|
||||
* \author
|
||||
* Christos Choutouridis AEM:8997
|
||||
* <cchoutou@ece.auth.gr>
|
||||
*/
|
||||
|
||||
#include <utils.h>
|
||||
#include <algorithm>
|
||||
|
||||
/*!
|
||||
* Initialize the matrix as Erdős-Rényi graph
|
||||
* \param A The matrix to initialize
|
||||
* \param p The probability of each edge
|
||||
*/
|
||||
void init_ER_graph (matrix& A, double p) {
|
||||
std::random_device rd;
|
||||
std::mt19937 gen(rd());
|
||||
std::binomial_distribution<> d(1, p);
|
||||
|
||||
#if CODE_VERSION == V12
|
||||
std::transform (A.begin(), A.end(), A.begin(),
|
||||
[&] (int x) { std::ignore =x; return d(gen); }
|
||||
#else
|
||||
A.for_each_in(0, A.size(), [&](auto i) {
|
||||
A.for_each_in(i+1, A.size(), [&](auto j){
|
||||
matrix::dataType edge = d(gen);
|
||||
if (edge) {
|
||||
A.set(edge, i, j);
|
||||
A.set(edge, j, i);
|
||||
}
|
||||
});
|
||||
});
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
* Utility to print the graph to sdtout
|
||||
*/
|
||||
void print_ER_graph (matrix& A) {
|
||||
matrix::indexType N = (A.size() < (matrix::indexType)session.print_size) ? A.size() : session.print_size;
|
||||
|
||||
A.for_each_in(0, N, [&](auto i){
|
||||
A.for_each_in(0, N, [&](auto j) {
|
||||
std::cout << A(i, j) << ' ';
|
||||
});
|
||||
std::cout << '\n';
|
||||
});
|
||||
}
|
||||
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
/*!
|
||||
* \file v12.cpp
|
||||
* \brief v1 and v2 part of the exercise.
|
||||
*
|
||||
* \author
|
||||
* Christos Choutouridis AEM:8997
|
||||
* <cchoutou@ece.auth.gr>
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <random>
|
||||
#include <v12.h>
|
||||
|
||||
namespace v12 {
|
||||
|
||||
/*!
|
||||
* A naive triangle counting algorithm
|
||||
* \param A The adjacency matrix
|
||||
* \return The number of triangles
|
||||
*/
|
||||
int triang_count (matrix& A) {
|
||||
int count =0;
|
||||
|
||||
// We use a symmetric matrix so we iterate using the constrain i<j<k
|
||||
A.for_each_in(0, A.size(), [&](auto i) {
|
||||
A.for_each_in(i+1, A.size(), [&](auto j) {
|
||||
A.for_each_in(j+1, A.size(), [&](auto k){
|
||||
count += (A(i,j) && A(i,k) && A(j,k)) ? 1:0;
|
||||
});
|
||||
});
|
||||
});
|
||||
return count;
|
||||
}
|
||||
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
/*!
|
||||
* \file v3.cpp
|
||||
* \brief vv3 part of the exercise.
|
||||
*
|
||||
* \author
|
||||
* Christos Choutouridis AEM:8997
|
||||
* <cchoutou@ece.auth.gr>
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <random>
|
||||
#include <v3.h>
|
||||
|
||||
namespace v3 {
|
||||
|
||||
using index_t = typename matrix::indexType;
|
||||
using value_t = typename matrix::dataType;
|
||||
|
||||
/*!
|
||||
* A naive triangle counting algorithm
|
||||
* \param A The adjacency matrix
|
||||
* \return The number of triangles
|
||||
*/
|
||||
std::vector<value_t> triang_v(matrix& A) {
|
||||
std::vector<value_t> c(A.size());
|
||||
|
||||
for (int i=0 ; i<A.size() ; ++i) {
|
||||
for (auto j = A.getCol(i); j.index() != j.end() ; ++j) // j list all the edges with i
|
||||
for (auto k = A.getCol(j.index()); k.index() != k.end() ; ++k) // k list all the edges with j
|
||||
for (auto ii = A.getCol(i) ; ii.index() <= k.index() ; ++ii) // search for i-k edge (this could be binary search)
|
||||
if (ii.index() == k.index()) ++c[i];
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
value_t sum (std::vector<value_t>& v) {
|
||||
value_t s =0;
|
||||
for (auto& it : v)
|
||||
s += it;
|
||||
return s;
|
||||
}
|
||||
|
||||
value_t triang_count (matrix& A) {
|
||||
auto v = triang_v(A);
|
||||
return sum(v);
|
||||
}
|
||||
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/*!
|
||||
* \file v4.cpp
|
||||
* \brief vv3 part of the exercise.
|
||||
*
|
||||
* \author
|
||||
* Christos Choutouridis AEM:8997
|
||||
* <cchoutou@ece.auth.gr>
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <random>
|
||||
#include <v4.h>
|
||||
|
||||
namespace v4 {
|
||||
|
||||
using index_t = typename matrix::indexType;
|
||||
using value_t = typename matrix::dataType;
|
||||
|
||||
|
||||
std::vector<value_t> mmacc_v(matrix& A, matrix& B) {
|
||||
std::vector<value_t> c(A.size());
|
||||
for (int i=0 ; i<A.size() ; ++i) {
|
||||
for (auto j = A.getRow(i); j.index() != j.end() ; ++j){
|
||||
c[i] += A.getRow(i)*B.getCol(j.index());
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
value_t sum (std::vector<value_t>& v) {
|
||||
value_t s =0;
|
||||
for (auto& it : v)
|
||||
s += it;
|
||||
return s;
|
||||
}
|
||||
|
||||
value_t triang_count (matrix& A) {
|
||||
auto v = mmacc_v(A, A);
|
||||
return (session.makeSymmetric) ? sum(v)/6 : sum(v);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user