#include #include #include #include #include #include #include #include #include #include #include #include "argProcessor.hpp" string usage(); using namespace std; static int VERBOSE_LEVEL = 0; int main(int argc, char* argv[]) { /* This program executes commands in Parallel using C++, the program is a wrapper designed for the orignal Trinity Program for seemless parallel OPENMP execution, Authors of this wrapper are MB Couger (mbcouger(AT Symbol)gmail.com, Matt Stowe mstowe(AT Symbol)okstate.edu*/ // code modified by bhaas for general cmd-line processing ArgProcessor args(argc, argv); bool shuffle_flag = false; int max_retries = 10; if (args.isArgSet("-help") || ! (args.isArgSet("-c") ) || ! (args.isArgSet("-CPU") ) ) { cerr << usage() << endl << endl; return(1); } if (args.isArgSet("-v")) { VERBOSE_LEVEL = 1; } else if (args.isArgSet("-vv")) { VERBOSE_LEVEL = 2; } if (args.isArgSet("-shuffle")) { shuffle_flag = true; } if (args.isArgSet("-max_retry")) { max_retries = args.getIntVal("-max_retry"); } string commands_file = args.getStringVal("-c"); int num_cpus = args.getIntVal("-CPU"); string failed_commands_filename = "FailedCommands"; if (args.isArgSet("-failed_cmds")) { failed_commands_filename = args.getStringVal("-failed_cmds"); } //declare variables start input stream ifstream in; // Create an input file stream. in.open(commands_file.c_str()); // Use it to read from a file named data.txt. if ( ! in ) { stringstream errstr; errstr << "Error, cannot open file : " << commands_file << endl; cerr << errstr.str(); exit(1); } // check to see if any commands had completed map previously_completed_commands; bool have_previously_completed_commands = false; ofstream successfully_completed_fh; { ifstream prev_completed_fh; stringstream completed_commands_filename_ss; completed_commands_filename_ss << commands_file << ".completed"; string completed_commands_filename = completed_commands_filename_ss.str(); prev_completed_fh.open(completed_commands_filename.c_str()); if (prev_completed_fh) { have_previously_completed_commands = true; string command_line; getline(prev_completed_fh, command_line); while(! prev_completed_fh.eof()) { previously_completed_commands[command_line] = true; getline(prev_completed_fh, command_line); } prev_completed_fh.close(); } successfully_completed_fh.open(completed_commands_filename.c_str(), ios_base::app); // open for append } long int NumberofCommands; NumberofCommands=0; vector commandsArray; string line; getline(in,line); int count_skip = 0; int max_report_skip = 10; while (! in.eof()) { if (have_previously_completed_commands && previously_completed_commands.find(line) != previously_completed_commands.end()) { // this command has been run before successfully, not running it again. count_skip++; if (VERBOSE_LEVEL and count_skip < max_report_skip) { cerr << "warning, command: " << line << " has successfully completed from a previous run. Skipping it here." << endl; if (count_skip >= max_report_skip) { cerr << "-reached max skip warning, turning off warnings for this." << endl; } } } else { NumberofCommands++; commandsArray.push_back(line); } getline(in,line); } if (VERBOSE_LEVEL) { cerr << "Number of Commands: " << NumberofCommands << endl; } //Parrell Execution of Individual Commands vector failedCommands; int num_failed_commands = 0; int num_succeeded_commands = 0; if (shuffle_flag) { random_shuffle(commandsArray.begin(), commandsArray.end()); } omp_set_dynamic(0); omp_set_num_threads(num_cpus); #pragma omp parallel for schedule (dynamic) for (long int i=0;i 0) { ss << ", failed(" << num_failed_commands << ")"; } int total_executed = num_succeeded_commands + num_failed_commands + count_skip; float percent_done = (float)total_executed/ (NumberofCommands+count_skip) * 100; ss << " " << percent_done << "% completed. "; #pragma omp critical (standard_error) cerr << ss.str(); } } successfully_completed_fh.close(); //ErrorCheckingOut if (num_failed_commands != 0) { ofstream outdata(failed_commands_filename.c_str()); for (int t=0;t :filename containing list of bash-style commands to execute." << endl << "# -CPU :number_of_threads" << endl << "#" << endl << "# Optional:" << endl << "# -max_retry :number of times to retry a command if it fails. (default: 10)" << endl << "# -shuffle :randomly shuffles the command order. " << endl << "# -failed_cmds :filename to capture failed commands. default(\"FailedCommands\")" << endl << "# -v :simple progress monitoring." << endl << "# -vv :increased verbosity in progress monitoring." << endl << "#" << endl << "##########################################################" << endl << endl; ss << "Note: This process creates a file named based on your commands filename with a .completed extension." << endl << "This enables a resume functionality, where if rerun, only those commands not completed successfully will be reprocessed." << endl << endl; return(ss.str()); }