PIPS
kernels.c File Reference

kernels manipulation More...

#include <ctype.h>
#include "genC.h"
#include "linear.h"
#include "ri.h"
#include "effects.h"
#include "ri-util.h"
#include "effects-util.h"
#include "text.h"
#include "pipsdbm.h"
#include "resources.h"
#include "properties.h"
#include "misc.h"
#include "control.h"
#include "callgraph.h"
#include "effects-generic.h"
#include "effects-simple.h"
#include "effects-convex.h"
#include "text-util.h"
#include "transformations.h"
#include "transformer.h"
#include "semantics.h"
#include "parser_private.h"
#include "accel-util.h"
+ Include dependency graph for kernels.c:

Go to the source code of this file.

Functions

static void kernel_load_store_generator (statement s, const char *module_name)
 Generate a communication around a statement instead of plain memory access if it is a call to a function named module_name. More...
 
static bool kernel_load_store_engine (const char *module_name, const string enginerc)
 run kernel load store using either region or effect engine More...
 
bool kernel_load_store (const char *module_name)
 Generate malloc/copy-in/copy-out on the call sites of this module. More...
 
static bool do_kernelize (statement s, entity loop_label)
 create a statement eligible for outlining into a kernel #1 find the loop flagged with loop_label #2 make sure the loop is // with local index #3 perform strip mining on this loop to make the kernel appear #4 perform two outlining to separate kernel from host More...
 
bool kernelize (const string module_name)
 turn a loop flagged with LOOP_LABEL into a kernel (GPU, terapix ...) More...
 
bool flag_kernel (const string module_name)
 
bool bootstrap_kernels (const string module_name)
 

Detailed Description

kernels manipulation

Author
Serge Guelton serge.nosp@m..gue.nosp@m.lton@.nosp@m.enst.nosp@m.-bret.nosp@m.agne.nosp@m..fr
Date
2010-01-03

Definition in file kernels.c.

Function Documentation

◆ bootstrap_kernels()

bool bootstrap_kernels ( const string  module_name)
Parameters
module_nameodule_name

Definition at line 297 of file kernels.c.

298 {
299  if (db_resource_p(DBR_KERNELS, ""))
300  pips_internal_error("kernels already initialized for %s", module_name);
301  callees kernels=make_callees(NIL);
302  DB_PUT_MEMORY_RESOURCE(DBR_KERNELS,"",kernels);
303  return true;
304 }
callees make_callees(list a)
Definition: ri.c:227
bool db_resource_p(const char *rname, const char *oname)
true if exists and in loaded or stored state.
Definition: database.c:524
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
#define DB_PUT_MEMORY_RESOURCE(res_name, own_name, res_val)
conform to old interface.
Definition: pipsdbm-local.h:66
#define pips_internal_error
Definition: misc-local.h:149

References DB_PUT_MEMORY_RESOURCE, db_resource_p(), make_callees(), module_name(), NIL, and pips_internal_error.

+ Here is the call graph for this function:

◆ do_kernelize()

static bool do_kernelize ( statement  s,
entity  loop_label 
)
static

create a statement eligible for outlining into a kernel #1 find the loop flagged with loop_label #2 make sure the loop is // with local index #3 perform strip mining on this loop to make the kernel appear #4 perform two outlining to separate kernel from host

Parameters
sstatement where the kernel can be found
loop_labellabel of the loop to be turned into a kernel
Returns
true as long as the kernel is not found

gather and check parameters

verify the loop is parallel

we can strip mine the loop

unfortunately, the strip mining does not exactly does what we want, fix it here

it is legal because we know the loop index is private, otherwise the end value of the loop index may be used incorrectly...

validate changes

recompute effects

outline the work and kernel parts

job done

Definition at line 162 of file kernels.c.

163 {
166  {
168  pips_user_error("you choosed a label of a non-doloop statement\n");
169 
170 
171 
173 
174  /* gather and check parameters */
175  int nb_nodes = get_int_property("KERNELIZE_NBNODES");
176  while(!nb_nodes)
177  {
178  string ur = user_request("number of nodes for your kernel?\n");
179  nb_nodes=atoi(ur);
180  }
181 
182  /* verify the loop is parallel */
184  pips_user_error("you tried to kernelize a sequential loop\n");
186  pips_user_error("you tried to kernelize a loop whose index is not private\n");
187 
188  if(nb_nodes >1 )
189  {
190  /* we can strip mine the loop */
192  /* unfortunately, the strip mining does not exactly does what we
193  want, fix it here
194 
195  it is legal because we know the loop index is private,
196  otherwise the end value of the loop index may be used
197  incorrectly...
198  */
199  {
201  entity outer_index = loop_index(statement_loop(s));
202  entity inner_index = loop_index(statement_loop(s2));
203  replace_entity(s2,inner_index,outer_index);
204  loop_index(statement_loop(s2))=outer_index;
205  replace_entity(loop_range(statement_loop(s2)),outer_index,inner_index);
206  if(!ENDP(loop_locals(statement_loop(s2)))) replace_entity(loop_locals(statement_loop(s2)),outer_index,inner_index);
207  loop_index(statement_loop(s))=inner_index;
208  replace_entity(loop_range(statement_loop(s)),outer_index,inner_index);
212  l = statement_loop(s);
213  }
214  }
215 
216  const char* kernel_name=get_string_property_or_ask("KERNELIZE_KERNEL_NAME","name of the kernel ?");
217  const char* host_call_name=get_string_property_or_ask("KERNELIZE_HOST_CALL_NAME","name of the fucntion to call the kernel ?");
218 
219  /* validate changes */
220  callees kernels=(callees)db_get_memory_resource(DBR_KERNELS,"",true);
221  callees_callees(kernels)= CONS(STRING,strdup(host_call_name),callees_callees(kernels));
222  DB_PUT_MEMORY_RESOURCE(DBR_KERNELS,"",kernels);
223 
231 
232  /* recompute effects */
233  proper_effects((string)module_local_name(cme));
234  cumulated_effects((string)module_local_name(cme));
238 
239  /* outline the work and kernel parts*/
240  outliner(kernel_name,make_statement_list(loop_body(l)));
241  (void)outliner(host_call_name,make_statement_list(s));
243 
244  /* job done */
245  gen_recurse_stop(NULL);
246 
247  }
248  return true;
249 }
int get_int_property(const string)
statement outliner(const char *, list)
outline the statements in statements_to_outline into a module named outline_module_name the outlined ...
Definition: outlining.c:1327
bool entity_is_argument_p(entity e, cons *args)
Definition: arguments.c:150
callees compute_callees(const statement stat)
Recompute the callees of a module statement.
Definition: callgraph.c:355
void set_cumulated_rw_effects(statement_effects)
void reset_cumulated_rw_effects(void)
bool cumulated_effects(const string)
bool proper_effects(const string)
#define STRING(x)
Definition: genC.h:87
statement make_block_statement(list)
Make a block statement from a list of statement.
Definition: statement.c:616
void reset_current_module_entity(void)
Reset the current module entity.
Definition: static.c:97
void reset_current_module_statement(void)
Reset the current module statement.
Definition: static.c:221
const char * get_current_module_name(void)
Get the name of the current module.
Definition: static.c:121
statement set_current_module_statement(statement)
Set the current module statement.
Definition: static.c:165
statement get_current_module_statement(void)
Get the current module statement.
Definition: static.c:208
entity set_current_module_entity(entity)
static.c
Definition: static.c:66
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
void replace_entity(void *s, entity old, entity new)
per variable version of replace_entities.
Definition: replace.c:113
void gen_recurse_stop(void *obj)
Tells the recursion not to go in this object.
Definition: genClib.c:3251
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
string db_get_memory_resource(const char *rname, const char *oname, bool pure)
Return the pointer to the resource, whatever it is.
Definition: database.c:755
loop statement_loop(statement)
Get the loop of a statement.
Definition: statement.c:1374
bool statement_loop_p(statement)
Definition: statement.c:349
#define pips_user_error
Definition: misc-local.h:147
string user_request(const char *,...)
int nb_nodes
The timing function.
Definition: prgm_mapping.c:101
const char * get_string_property_or_ask(const char *, const char[])
bool module_reorder(statement body)
Reorder a module and recompute order to statement if any.
Definition: reorder.c:244
#define make_statement_list(stats...)
easy list constructor
bool same_entity_p(entity e1, entity e2)
predicates on entities
Definition: entity.c:1321
const char * module_local_name(entity e)
Returns the module local user name.
Definition: entity.c:582
void AddLocalEntityToDeclarations(entity, entity, statement)
Add the variable entity e to the list of variables of the function module.
Definition: variable.c:233
void RemoveLocalEntityFromDeclarations(entity, entity, statement)
Definition: variable.c:120
#define loop_body(x)
Definition: ri.h:1644
struct _newgen_struct_callees_ * callees
Definition: ri.h:55
#define loop_execution(x)
Definition: ri.h:1648
#define instruction_loop_p(x)
Definition: ri.h:1518
#define callees_callees(x)
Definition: ri.h:675
#define instruction_loop(x)
Definition: ri.h:1520
#define statement_label(x)
Definition: ri.h:2450
#define execution_sequential_p(x)
Definition: ri.h:1208
#define loop_label(x)
Definition: ri.h:1646
#define loop_locals(x)
Definition: ri.h:1650
#define statement_instruction(x)
Definition: ri.h:2458
#define loop_range(x)
Definition: ri.h:1642
#define loop_index(x)
Definition: ri.h:1640
char * strdup()
statement loop_strip_mine(statement loop_statement, int chunk_size, int chunk_number)
loop_strip_mine():
Definition: strip_mine.c:64

References AddLocalEntityToDeclarations(), callees_callees, compute_callees(), CONS, cumulated_effects(), db_get_memory_resource(), DB_PUT_MEMORY_RESOURCE, ENDP, entity_is_argument_p(), execution_sequential_p, gen_recurse_stop(), get_current_module_entity(), get_current_module_name(), get_current_module_statement(), get_int_property(), get_string_property_or_ask(), instruction_loop, instruction_loop_p, loop_body, loop_execution, loop_index, loop_label, loop_locals, loop_range, loop_strip_mine(), make_block_statement(), make_statement_list, module_local_name(), module_reorder(), nb_nodes, outliner(), pips_user_error, proper_effects(), RemoveLocalEntityFromDeclarations(), replace_entity(), reset_cumulated_rw_effects(), reset_current_module_entity(), reset_current_module_statement(), same_entity_p(), set_cumulated_rw_effects(), set_current_module_entity(), set_current_module_statement(), statement_instruction, statement_label, statement_loop(), statement_loop_p(), strdup(), STRING, and user_request().

Referenced by kernelize().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ flag_kernel()

bool flag_kernel ( const string  module_name)
Parameters
module_nameodule_name

Definition at line 287 of file kernels.c.

288 {
289  if (!db_resource_p(DBR_KERNELS, ""))
290  pips_internal_error("kernels not initialized for %s", module_name);
291  callees kernels=(callees)db_get_memory_resource(DBR_KERNELS,"",true);
293  DB_PUT_MEMORY_RESOURCE(DBR_KERNELS,"",kernels);
294  return true;
295 }

References callees_callees, CONS, db_get_memory_resource(), DB_PUT_MEMORY_RESOURCE, db_resource_p(), module_name(), pips_internal_error, strdup(), and STRING.

+ Here is the call graph for this function:

◆ kernel_load_store()

bool kernel_load_store ( const char *  module_name)

Generate malloc/copy-in/copy-out on the call sites of this module.

kernels.c

based on convex array regions

Parameters
module_nameodule_name

Definition at line 143 of file kernels.c.

143  {
144  return kernel_load_store_engine(module_name, DBR_REGIONS);
145 }
static bool kernel_load_store_engine(const char *module_name, const string enginerc)
run kernel load store using either region or effect engine
Definition: kernels.c:93

References kernel_load_store_engine(), and module_name().

+ Here is the call graph for this function:

◆ kernel_load_store_engine()

static bool kernel_load_store_engine ( const char *  module_name,
const string  enginerc 
)
static

run kernel load store using either region or effect engine

Parameters
[in]module_nameis the name of the function we want to isolate with communications and memory allocations
[in]enginercis the name of the resources to use to analyse which data need to be allocated and transfers. It can be DBR_REGIONS (more precise) or DBR_EFFECTS

generate a load stores on each caller

prelude

o the job

validate

ostlude

lag the module as kernel if not done

Definition at line 93 of file kernels.c.

94  {
95  /* generate a load stores on each caller */
96 
97  debug_on("KERNEL_LOAD_STORE_DEBUG_LEVEL");
98 
99  callees callers = (callees)db_get_memory_resource(DBR_CALLERS,module_name,true);
101  /* prelude */
108  /*do the job */
111  /* validate */
115 
116  /*postlude*/
123  }
124 
125  /*flag the module as kernel if not done */
126  callees kernels = (callees)db_get_memory_resource(DBR_KERNELS,"",true);
127  bool found = false;
128  FOREACH(STRING,kernel_name,callees_callees(kernels))
129  if( (found=(same_string_p(kernel_name,module_name))) ) break;
130  if(!found)
132  db_put_or_update_memory_resource(DBR_KERNELS,"",kernels,true);
133 
134  debug_off();
135 
136  return true;
137 }
static const char * caller_name
Definition: alias_check.c:122
void reset_proper_rw_effects(void)
void set_proper_rw_effects(statement_effects)
#define gen_context_recurse(start, ctxt, domain_number, flt, rwt)
Definition: genC.h:285
bool gen_true2(__attribute__((unused)) gen_chunk *u1, __attribute__((unused)) void *u2)
Definition: genClib.c:2785
#define FOREACH(_fe_CASTER, _fe_item, _fe_list)
Apply/map an instruction block on all the elements of a list.
Definition: newgen_list.h:179
void db_put_or_update_memory_resource(const char *rname, const char *oname, void *p, bool update_is_ok)
Put a resource into the current workspace database.
Definition: database.c:854
static void kernel_load_store_generator(statement s, const char *module_name)
Generate a communication around a statement instead of plain memory access if it is a call to a funct...
Definition: kernels.c:66
#define debug_on(env)
Definition: misc-local.h:157
#define debug_off()
Definition: misc-local.h:160
#define same_string_p(s1, s2)
entity module_name_to_entity(const char *mn)
This is an alias for local_name_to_top_level_entity.
Definition: entity.c:1479
#define statement_domain
newgen_sizeofexpression_domain_defined
Definition: ri.h:362
void module_to_value_mappings(entity m)
void module_to_value_mappings(entity m): build hash tables between variables and values (old,...
Definition: mappings.c:624
void reset_precondition_map(void)
void set_precondition_map(statement_mapping)
void free_value_mappings(void)
Normal call to free the mappings.
Definition: value.c:1212

References callees_callees, caller_name, compute_callees(), CONS, db_get_memory_resource(), DB_PUT_MEMORY_RESOURCE, db_put_or_update_memory_resource(), debug_off, debug_on, FOREACH, free_value_mappings(), gen_context_recurse, gen_true2(), get_current_module_entity(), get_current_module_statement(), kernel_load_store_generator(), module_name(), module_name_to_entity(), module_reorder(), module_to_value_mappings(), reset_cumulated_rw_effects(), reset_current_module_entity(), reset_current_module_statement(), reset_precondition_map(), reset_proper_rw_effects(), same_string_p, set_cumulated_rw_effects(), set_current_module_entity(), set_current_module_statement(), set_precondition_map(), set_proper_rw_effects(), statement_domain, strdup(), and STRING.

Referenced by kernel_load_store().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ kernel_load_store_generator()

static void kernel_load_store_generator ( statement  s,
const char *  module_name 
)
static

Generate a communication around a statement instead of plain memory access if it is a call to a function named module_name.

Parameters
[in,out]sis the statment to isolate with some communication arounds
[in]module_nameis the name of the function to isolate

Generate communication operations around the call to a function named "module_name".

Definition at line 66 of file kernels.c.

67 {
68  if(statement_call_p(s))
69  {
70  call c = statement_call(s);
71  /* Generate communication operations around the call to a function
72  named "module_name". */
74  {
75  const char* prefix = get_string_property ("KERNEL_LOAD_STORE_VAR_PREFIX");
76  const char* suffix = get_string_property ("KERNEL_LOAD_STORE_VAR_SUFFIX");
77  pips_debug (5, "kernel_load_store used prefix : %s\n", prefix);
78  pips_debug (5, "kernel_load_store used suffix : %s\n", suffix);
79  do_isolate_statement(s, prefix, suffix);
80  }
81  }
82 }
void do_isolate_statement(statement, const char *, const char *)
perform statement isolation on statement s that is make sure that all access to variables in s are ma...
char * get_string_property(const char *)
call statement_call(statement)
Get the call of a statement.
Definition: statement.c:1406
bool statement_call_p(statement)
Definition: statement.c:364
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
static const char * prefix
#define call_function(x)
Definition: ri.h:709

References call_function, do_isolate_statement(), get_string_property(), module_local_name(), module_name(), pips_debug, prefix, same_string_p, statement_call(), and statement_call_p().

Referenced by kernel_load_store_engine().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ kernelize()

bool kernelize ( const string  module_name)

turn a loop flagged with LOOP_LABEL into a kernel (GPU, terapix ...)

Parameters
module_namename of the module
Returns
true

prelude

retreive loop label

run kernelize

validate

ostlude

Parameters
module_nameodule_name

Definition at line 259 of file kernels.c.

260 {
261  /* prelude */
264 
265  /* retreive loop label */
266  const char* loop_label_name = get_string_property_or_ask("LOOP_LABEL","label of the loop to turn into a kernel ?\n");
267  entity loop_label_entity = find_label_entity(module_name,loop_label_name);
268  if( entity_undefined_p(loop_label_entity) )
269  pips_user_error("label '%s' not found in module '%s' \n",loop_label_name,module_name);
270 
271 
272  /* run kernelize */
275 
276  /* validate */
280 
281  /*postlude*/
284  return true;
285 }
void gen_null2(__attribute__((unused)) void *u1, __attribute__((unused)) void *u2)
idem with 2 args, to please overpeaky compiler checks
Definition: genClib.c:2758
static bool do_kernelize(statement s, entity loop_label)
create a statement eligible for outlining into a kernel #1 find the loop flagged with loop_label #2 m...
Definition: kernels.c:162
entity find_label_entity(const char *, const char *)
util.c
Definition: util.c:43
#define entity_undefined_p(x)
Definition: ri.h:2762

References compute_callees(), db_get_memory_resource(), DB_PUT_MEMORY_RESOURCE, do_kernelize(), entity_undefined_p, find_label_entity(), gen_context_recurse, gen_null2(), get_current_module_statement(), get_string_property_or_ask(), module_name(), module_name_to_entity(), module_reorder(), pips_user_error, reset_current_module_entity(), reset_current_module_statement(), set_current_module_entity(), set_current_module_statement(), and statement_domain.

+ Here is the call graph for this function: