// Example 4.1. See page 19 of the FG tutorial. #include "FG.h" #include #include using namespace std; // Class to package together ints for max and min. class My_stage_params { public : int max, min; }; // Stage function prototypes. int create_func(FG_stage, FG_stage_params); int max_min_func(FG_stage, FG_stage_params); int main() { // Initialize the seed, because we'll be generating random numbers. srand(time(0)); // Initialize N, the number of ints in each buffer. const int N = 100; // Declare the pipeline variables. int buffer_size = sizeof(int) * N; int num_rounds = 10; // Declare the threads, and store them in a NULL-terminated array. FG_pipeline_thread_helper create_thread = new FG_pipeline_thread_helper_info(), max_min_thread = new FG_pipeline_thread_helper_info(); FG_pipeline_thread_helper threads[] = {create_thread, max_min_thread, NULL}; // Create and initialize a My_stage_params object. My_stage_params *max_min_params = new My_stage_params(); max_min_params->max = INT_MIN; max_min_params->min = INT_MAX; // Declare the stages. FG_pipeline_stage_helper create_stage = new FG_pipeline_stage_helper_info(create_thread), max_min_stage = new FG_pipeline_stage_helper_info(max_min_thread); // Assign a function to each stage. create_stage->set_func(create_func, NULL); max_min_stage->set_func(max_min_func, max_min_params); // Store the stages in a NULL-terminated array. FG_pipeline_stage_helper stages[] = {create_stage, max_min_stage, NULL}; // Instantiate the pipeline. FG_pipeline my_pipeline = FG_pipeline_info::create(stages, threads); // Set the pipeline variables. my_pipeline->set_buff_size(buffer_size); my_pipeline->set_num_rounds(num_rounds); // Fix the pipeline, which also runs it, and store the return code. int error = my_pipeline->fix(); // Display the return code. cout << "FINISHED PIPELINE WITH ERROR CODE " << error << endl; // Dismantle the pipeline. my_pipeline->dismantle(); return 0; } int create_func(FG_stage my_stage, FG_stage_params my_params) { // Set a limit for the randomly generated numbers. const int LIMIT = 4096; // Accept a thumbnail from the preceding stage, and store the // location of its buffer. FG_pipeline_thumbnail thumb = my_stage->accept_thumbnail(); int *buff = (int *) thumb->get_address(); // Determine how many ints the buffer holds. int n = thumb->get_size() / sizeof(int); // Randomly generate n integers and store them in the buffer. for (int i = 0; i < n; i++) { buff[i] = rand() % LIMIT; } // Convey the thumbnail to the next stage. my_stage->convey_thumbnail(thumb); return 0; } // Stage to compute the max and min values ever seen in all buffers, // and to print these values once the caboose comes through. int max_min_func(FG_stage my_stage, FG_stage_params my_params) { // Accept a thumbnail from the preceding stage, and save the // location of its buffer. FG_pipeline_thumbnail thumb = my_stage->accept_thumbnail(); int *buff = (int *) thumb->get_address(); // Determine how many ints the buffer holds. int n = thumb->get_size() / sizeof(int); // Cast my_params to be a pointer to My_stage_params. My_stage_params *max_min_params = (My_stage_params *) my_params; // Go through the buffer, updating max and min as needed. for (int i = 0; i < n; i++) { if (buff[i] > max_min_params->max) max_min_params->max = buff[i]; if (buff[i] < max_min_params->min) max_min_params->min = buff[i]; } // If this buffer is the caboose, print out the max and min values // ever seen. if (thumb->get_caboose()) cout << "max = " << max_min_params->max << ", min = " << max_min_params->min << endl; // Convey the thumbnail to the next stage. my_stage->convey_thumbnail(thumb); return 0; }