A triangle counting assignment for A.U.TH Parallel and distributed systems class.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

163 lines
4.7 KiB

  1. /*!
  2. * \file main.cpp
  3. * \brief Main application file
  4. *
  5. * \author
  6. * Christos Choutouridis AEM:8997
  7. * <cchoutou@ece.auth.gr>
  8. */
  9. #include <iostream>
  10. #include <string>
  11. #include <exception>
  12. #include <utils.h>
  13. #include <config.h>
  14. // Global session data
  15. session_t session;
  16. Log logger;
  17. /*!
  18. * A small command line argument parser
  19. * \return The status of the operation
  20. */
  21. bool get_options(int argc, char* argv[]){
  22. bool status =true;
  23. // iterate over the passed arguments
  24. for (int i=1 ; i<argc ; ++i) {
  25. std::string arg(argv[i]); // get current argument
  26. if (arg == "-i" || arg == "--input") {
  27. session.inputMatrix = InputMatrix::MTX;
  28. if (i+1 < argc)
  29. session.mtxFile = std::ifstream(argv[++i]);
  30. else
  31. status = false;
  32. }
  33. else if (arg == "-o" || arg == "--output") {
  34. session.outputMode = OutputMode::FILE;
  35. if (i+1 < argc)
  36. session.outFile = std::ofstream(argv[++i]);
  37. else
  38. status = false;
  39. }
  40. else if (arg == "-g" || arg == "--generate") {
  41. session.inputMatrix = InputMatrix::GENERATE;
  42. if (i+2 < argc) {
  43. session.gen_size = std::atoi(argv[++i]);
  44. session.gen_prob = std::atof(argv[++i]);
  45. }
  46. else
  47. status = false;
  48. }
  49. else if (arg == "-n" || arg == "--max_trheads") {
  50. session.max_threads = (i+1 < argc) ? std::atoi(argv[++i]) : session.max_threads;
  51. }
  52. else if (arg == "-t" || arg == "--timing")
  53. session.timing = true;
  54. else if (arg == "-v" || arg == "--verbose")
  55. session.verbose = true;
  56. else if (arg == "--triangular_only")
  57. session.makeSymmetric = false;
  58. else if (arg == "--validate_mtx")
  59. session.validate_mtx = true;
  60. else if (arg == "--print_count")
  61. session.print_count = true;
  62. else if (arg == "--print_graph") {
  63. session.mtx_print = true;
  64. session.mtx_print_size = (i+1 < argc) ? std::atoi(argv[++i]) : session.mtx_print_size;
  65. }
  66. else if (arg == "-h" || arg == "--help") {
  67. std::cout << "Help message\n";
  68. exit(0);
  69. }
  70. else { // parse error
  71. std::cout << "Error message\n";
  72. status = false;
  73. }
  74. }
  75. // Input checkers
  76. if (session.inputMatrix == InputMatrix::UNSPECIFIED) {
  77. std::cout << "Error message\n";
  78. status = false;
  79. }
  80. return status;
  81. }
  82. /*!
  83. * get or generate matrix
  84. * \param A Reference to matrix for output (move using RVO)
  85. * \param timer Reference to timer utility to access time printing functionality
  86. */
  87. void prepare_matrix (matrix& A, Timing& timer) {
  88. if (session.inputMatrix == InputMatrix::GENERATE) {
  89. logger << "Initialize matrix with size: " << session.gen_size << " and probability: " << session.gen_prob << logger.endl;
  90. timer.start();
  91. A.size(session.gen_size);
  92. init_ER_graph(A, session.gen_prob);
  93. timer.stop();
  94. timer.print_dt("generate matrix");
  95. }
  96. else {
  97. logger << "Read matrix from file" << logger.endl;
  98. timer.start();
  99. if (session.validate_mtx && !Mtx::is_triangular<matrix::indexType> (session.mtxFile))
  100. throw std::runtime_error("Error: Matrix is not strictly upper or lower");
  101. if (!Mtx::load (A, session.mtxFile)) {
  102. throw std::runtime_error("Error: fail to load matrix");
  103. }
  104. timer.stop();
  105. logger << "Matrix size: " << A.size() << " and capacity: " << A.capacity() << logger.endl;
  106. timer.print_dt("load matrix");
  107. }
  108. if (session.verbose && session.mtx_print) {
  109. logger << "\nMatrix:" << logger.endl;
  110. print_graph (A);
  111. }
  112. }
  113. /*
  114. * main program
  115. */
  116. int main(int argc, char* argv[]) try {
  117. Timing timer;
  118. matrix A;
  119. std::vector<value_t> c;
  120. index_t s;
  121. // try to read command line
  122. if (!get_options(argc, argv))
  123. exit(1);
  124. prepare_matrix(A, timer);
  125. threads_info();
  126. logger << "Create count vector" << logger.endl;
  127. timer.start();
  128. c = triang_v (A);
  129. timer.stop();
  130. timer.print_dt("create count vector");
  131. if (session.print_count) {
  132. logger << "Calculate total triangles" << logger.endl;
  133. timer.start();
  134. s = triang_count(c);
  135. timer.stop();
  136. logger << "There are " << s << " triangles" << logger.endl;
  137. timer.print_dt("calculate sum");
  138. }
  139. // output results
  140. if (session.print_count)
  141. triangle_out (s, (session.outputMode == OutputMode::FILE) ? session.outFile : std::cout);
  142. else
  143. vector_out (c, (session.outputMode == OutputMode::FILE) ? session.outFile : std::cout);
  144. return 0;
  145. }
  146. catch (std::exception& e) {
  147. //we probably pollute the user's screen. Comment `cerr << ...` if you don't like it.
  148. std::cerr << e.what() << '\n';
  149. exit(1);
  150. }