Plugins

Plugins of Nestor.

plug_set_name
Sets the name of a plugin
plug_set_summary
Sets the long summary of a plugin
plug_set_description
Sets the short description of a plugin
plug_set_copyright
Sets the copyright information of a plugin
plugarg
plug_set_arguments
To use if the plugin has arguments
plug_add_argument
Adds an argument to the plugin
plug_add_argument_element
Adds an element to a P_SET argument of the plugin
plug_get_argument
Gets the current value of the argument identified by what
plug_get_tree
Gets the tree argument of the plugin
plug_get_report
Gets the name of the file to use as a report file
plug_set_tree
Sets the result tree of the plugin
plug_set_report
Sets the name of the report file used
plug_set_error
Sets the error string

A plugin is a code transformation. A plugin is a piece of C++ code that gets a part of a tree (an NstTree object). This tree can be transformed, analyzed, and the result must be returned by the plugin. A plugin is dynamically linked by GTK Nestor when it is used. A plugin must always provide two functions: plugin_init and plugin_run. the first function sets the parameters of the plugin, its name, its description, etc... In the case of GTK Nestor, the arguments of the plugin automatically build a GUI when the plugin is selected. The function plugin_run is the function that is called when the plugin is applied to a piece of code.

Here is the example of a plugin that checks if the loops that are under the NstTree object passed as parameter are parallel or not. This plugin uses the class CheckParallelLoop to check if a loop is parallel. This code can be found under the directory src/plugins/test_plug. To add a new plugin, just create a new directory under the directory src/plugins, copy the Makefile from another plugin's source directory, write the code of your plugin and that's it. Just type make in the main directory of Nestor, and your plugin will be copied into bin/plugins and recognized by GTK Nestor.

     #include <nst_plug.H>

     #define NAME "Check parallel loop"
     #define DESC "\
     Checks if a loop nest is parallel.\n\
     Adds a directive in front of the loop \n\
     nest if the loop is parallel.\n"
     #define COPYRIGHT "no copyright"
     #define SUMM "Adds a directive if a loop nest is parallel"

     int plugin_init(struct arglist* desc)
     {
             plug_set_name(desc, NAME);
             plug_set_description(desc, DESC);
             plug_set_summary(desc, SUMM);
             plug_set_copyright(desc, COPYRIGHT);
             return(0);
     }

     int plugin_run(struct arglist * args)
     {
       NstTree* tree = plug_get_tree(args);
       char* report_file = plug_get_report(args);
       if (!tree || !report_file)
         return 1;

       ofstream plug(report_file);  
       if (!plug)
         {
           plug_set_error(args, "Cannot open report file.");
           return 1;
         }

       CheckParallelLoop checker(*tree, (ofstream*)&plug);

       plug_set_report(args, report_file);  
       plug_set_tree(args, tree);

       return 0;
     }

Here is another example that has parameters. This example adds a data distribution for a given array declaration. This distribution is added at the end of the declaration list. If a distribution already exists, it is replaced by the new distribution. This plugin can be found under the directory src/plugins/insert_distri.

     #include <nst_plug.H>

     #define NAME "Adds a distribution"
     #define DESC "\
     Inserts an HPF distribution by BLOCK for an array that is already\n\
     declared.\n"
     #define COPYRIGHT "no copyright"
     #define SUMM "Inserts an HPF BLOCK distribution for an array"

     void insert_distribution(NstDeclarationVariable* dv, int, int);
     void modify_distribution(NstDeclarationDistribute* dd, NstDeclarationVariable* dv, int, int);
     NstDeclarationDistribute* search_existing_distribution(NstDeclarationList* father,
                                                            NstDeclarationVariable* dv);

     int plugin_init(struct arglist* desc)
     {
             plug_set_name(desc, NAME);
             plug_set_description(desc, DESC);
             plug_set_summary(desc, SUMM);
             plug_set_copyright(desc, COPYRIGHT);

       plug_set_arguments(desc);
       plug_add_argument(desc, "Type of distribution", P_SET, NULL);
       // This element has the number 2.
       plug_add_argument_element(desc, "Type of distribution", "BLOCK");
       // This element has the number 1.
       plug_add_argument_element(desc, "Type of distribution", "CYCLIC");
       plug_add_argument(desc, "Size of distribution", P_INT, (void*)0);
             return(0);
     }

     int plugin_run(struct arglist * args)
     {
       NstTree* tree = plug_get_tree(args);
       NstDeclarationList* father = dynamic_cast<NstDeclarationList*>(tree->in());
       NstDeclarationVariable* dv = dynamic_cast<NstDeclarationVariable*>(tree);
       if (!dv)
         {
           plug_set_error(args, "This plugin expects a variable declaration.");
           return 1;
         }
       if (!father)
         {
           plug_set_error(args, "I need a declaration list to insert a distribution.");
           return 1;
         }

       int dtype = (int)plug_get_argument(args, "Type of distribution");
       int dsize = (int)plug_get_argument(args, "Size of distribution");

       if (NstDeclarationDistribute* old_dist = search_existing_distribution(father, dv))
         modify_distribution(old_dist, dv, dtype, dsize);
       else
         insert_distribution(dv, dtype, dsize);

       plug_set_tree(args, (NstTree*)father);
       return 0;
     }


     NstDeclarationDistribute* search_existing_distribution(NstDeclarationList* father,
                                                            NstDeclarationVariable* dv)
     {
       NstDeclarationDistribute* ret = NULL;
       NstDeclarationList::iterator it = father->begin();
       for(; it != father->end(); it++)
         if (ret = dynamic_cast<NstDeclarationDistribute*>(*it))
           if (ret->definition() == dv->definition())
             return ret;
       return NULL;
     }

     NstDistformat* create_dist(int dtype, int dsize)
     {
       NstExpression* sz;
       if (dsize > 0)
         {
           NstInteger taille(dsize);
           sz = new NstExpressionConstant(taille);
         }
       else
         {
           sz = new NstExpressionDummy;
         }
       NstDistformat* df;
       if (dtype == 2)
         {
           df = new NstDistformatBlock(*sz);
         }
       else if (dtype == 1)
         {
           df = new NstDistformatCyclic(*sz);
         }
       assert(df);
       return df;
     }
     void modify_distribution(NstDeclarationDistribute* dd, NstDeclarationVariable* dv, int dtype, int dsize)
     {
       if (NstTypeArray* ta = dynamic_cast<NstTypeArray*>(dv->variable_type()))
         {
           int size = ta->shapes.size();
           NstDistributionNode def_dist;
           NstDistformat* df = create_dist(dtype, dsize);
           while(size--)
             def_dist.mapping.push_back(*df);
           dd->distribution(def_dist);
         }
     }

     void insert_distribution(NstDeclarationVariable* dv, int dtype, int dsize)
     {
       if (NstTypeArray* ta = dynamic_cast<NstTypeArray*>(dv->variable_type()))
         {
           int size = ta->shapes.size();
           NstDistributionNode def_dist;
           NstDistformat* df = create_dist(dtype, dsize);
           while(size--)
             def_dist.mapping.push_back(*df);
           NstProcessorDefault proc_def;
           NstDeclarationDistribute dist(*dv->definition(), def_dist, proc_def);
           NstDeclarationList *dl = dynamic_cast<NstDeclarationList*>(dv->in());
           assert(dl);
           dl->push_back(dist);
         }
     }

alphabetic index hierarchy of classes


this page has been generated automatically by doc++

(c)opyright by Malte Zöckler, Roland Wunderling
contact: doc++@zib.de