Skip to content

Commit

Permalink
Merge pull request #214 from benchmark-subsetting/recursive-codelets
Browse files Browse the repository at this point in the history
Support for recursive codelets capture
  • Loading branch information
PurplePachyderm authored Sep 27, 2023
2 parents 46b288a + dc4cd27 commit 4659339
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 31 deletions.
11 changes: 9 additions & 2 deletions src/RegionDump/LoopRegionDump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,8 +220,9 @@ bool LoopRegionDump::visitLoop(Loop *L, Module *mod) {
/* Create after_dump function */
Function *func_after_dump = mod->getFunction("after_dump");
if (!func_after_dump) { // If function "after_dump" not found, creates it
// Create a void type
// Create a params vector (char *)
std::vector<Type *> FuncTy_12_args;
FuncTy_12_args.push_back(PointerType::get(IntegerType::get(mod->getContext(), 8), 0));
FunctionType *AfterDumpFuncTy = FunctionType::get(
/*Result=*/Type::getVoidTy(mod->getContext()),
/*Params=*/FuncTy_12_args,
Expand Down Expand Up @@ -252,7 +253,13 @@ bool LoopRegionDump::visitLoop(Loop *L, Module *mod) {
for (SmallVectorImpl<BasicBlock *>::iterator I = exitblocks.begin(),
E = exitblocks.end();
I != E; ++I) {
CallInst::Create(func_after_dump, "", &(*I)->front());
// Build after_dump params
IRBuilder<> builder(*I);
std::vector<Value *> ad_funcParameter;
ad_funcParameter.push_back(builder.CreateGlobalStringPtr(currFunc->getName()));

// Insert call
CallInst::Create(func_after_dump, ad_funcParameter, "", &(*I)->front());
}

return true;
Expand Down
9 changes: 8 additions & 1 deletion src/RegionDump/OmpRegionDump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ bool OmpRegionDump::runOnFunction(Function &F) {
if (!func_after_dump) { // If function "after_dump" not found, creates it
// Create a void type
std::vector<Type *> FuncTy_12_args;
FuncTy_12_args.push_back(PointerType::get(IntegerType::get(mod->getContext(), 8), 0));
FunctionType *AfterDumpFuncTy = FunctionType::get(
/*Result=*/Type::getVoidTy(mod->getContext()),
/*Params=*/FuncTy_12_args,
Expand All @@ -237,7 +238,13 @@ bool OmpRegionDump::runOnFunction(Function &F) {
for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
if (insertMarker) {
Instruction *pinst = dyn_cast<Instruction>(&*I);
CallInst::Create(func_after_dump, "", pinst);

// Build after_dump params
IRBuilder<> builder(pinst->getParent());
std::vector<Value *> ad_funcParameter;
ad_funcParameter.push_back(builder.CreateGlobalStringPtr(currFunc->getName()));

CallInst::Create(func_after_dump, ad_funcParameter, "", pinst);
insertMarker = false;
}

Expand Down
110 changes: 83 additions & 27 deletions src/memory_dump/tracee.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ typedef struct {
} InvocsCounterCollection;

static InvocsCounterCollection invocs_counters;
//static bool in_progress = false;
static InvocsCounterCollection after_dump_invocs_counters;

static char* in_progress_codelet_name = NULL;
static int in_progress_invocation = -1;

Expand All @@ -92,6 +93,27 @@ static InvocsCounter* get_counter_internal(const char* codelet_name) {
return &(invocs_counters.counters[invocs_counters.num_counters-1]);
}

static InvocsCounter* get_after_dump_counter_internal(const char* codelet_name) {
for (int i = 0; i < after_dump_invocs_counters.num_counters; i++) {
InvocsCounter* counter = &(after_dump_invocs_counters.counters[i]);
if (strcmp(counter->codelet_name, codelet_name) == 0) {
return counter;
}
}
// New counter
InvocsCounter newCounter;
newCounter.codelet_name = strdup(codelet_name);
newCounter.count_value = 0;

after_dump_invocs_counters.counters = realloc(
after_dump_invocs_counters.counters, (after_dump_invocs_counters.num_counters + 1) * sizeof(InvocsCounter)
);
after_dump_invocs_counters.counters[after_dump_invocs_counters.num_counters] = newCounter;
after_dump_invocs_counters.num_counters++;
return &(after_dump_invocs_counters.counters[after_dump_invocs_counters.num_counters-1]);
}


void increment_counter(const char* codelet_name) {
get_counter_internal(codelet_name)->count_value ++;
}
Expand All @@ -100,6 +122,15 @@ unsigned long long get_counter_value(const char* codelet_name) {
return get_counter_internal(codelet_name)->count_value;
}

void increment_after_dump_counter(const char* codelet_name) {
get_after_dump_counter_internal(codelet_name)->count_value ++;
}

unsigned long long get_after_dump_counter_value(const char* codelet_name) {
return get_after_dump_counter_internal(codelet_name)->count_value;
}


/*************************/


Expand Down Expand Up @@ -245,7 +276,21 @@ int split (char* str, int ** tokens) {
return ntokens;
}

/*

bool find_invocation(char *invocations_str, int times_called) {
int * invocations = NULL;
int n_invocations = split(invocations_str, &invocations);

int i;
for(i=0; i<n_invocations; i++) {
if (times_called == invocations[i]) {
free(invocations);
return true;
}
}
free(invocations);
return false;
}


/* dump: requests capture of a outlined region of interest. Must be called
Expand All @@ -257,79 +302,90 @@ int split (char* str, int ** tokens) {
* - ... are the arguments passed to the outlined function
*/
void dump(char *loop_name, char *invocations_str, int arg_count, ...) {
/* Must be conserved ? */
/* Avoid doing something before initializing */
/* the dump. */
if (!dump_initialized)
return;

increment_counter(loop_name);
int times_called = get_counter_value(loop_name);

int * invocations = NULL;
int n_invocations = split(invocations_str, &invocations);
if (in_progress_codelet_name != NULL)
return;

bool invocToCapture = false;
int i;
for(i=0; i<n_invocations; i++) {
if (times_called == invocations[i]) {
invocToCapture = true;
break;
}
}
if(!invocToCapture) {
free(invocations);

int times_called = get_counter_value(loop_name);
bool to_capture = find_invocation(invocations_str, times_called);
if(!to_capture)
return;
}

// This information is useful to match dump and after_dump calls
// (in case of recursive codelets)
in_progress_codelet_name = strdup(loop_name);
in_progress_invocation = times_called;

mtrace_active = true;
send_to_tracer(TRAP_LOCK_MEM);

in_codelet = true;

assert(times_called == invocations[i]);
mtrace_active = false;

strcpy(tracer_buff.str_tmp, loop_name);
int captured_invoc = invocations[i];
free(invocations);

/* Send args */
send_to_tracer(TRAP_START_ARGS);
send_to_tracer(captured_invoc);
send_to_tracer(in_progress_invocation);
send_to_tracer(arg_count);

/* Dump addresses */
va_list ap;
va_start(ap, arg_count);
for (i = 0; i < arg_count; i++) {
for (int i = 0; i < arg_count; i++) {
send_to_tracer((register_t)va_arg(ap, void *));
}
va_end(ap);

send_to_tracer(TRAP_END_ARGS);
}

void after_dump(void) {
void after_dump(char *loop_name) {
debug_print("[tracee %d] In after_dump\n", getpid());
/* Avoid doing something before initializing */
/* the dump. */
if (!dump_initialized || !in_codelet)
return;


// Increment number of after_dump calls for the codelet
// (useful to match call & after_dump call for recursive codelets)
increment_after_dump_counter(loop_name);

// Check if we're stopping the correct codelet
if (in_progress_codelet_name != NULL && strcmp(in_progress_codelet_name, loop_name) != 0)
return;

// Check if invoc counters of dump and after_dump match for this codelet.
// If so, stop dump
int n_ad_calls = get_after_dump_counter_value(loop_name);
int n_calls = get_counter_value(loop_name);
if(n_ad_calls != n_calls)
return;

in_codelet = false;
pid_t parent = getppid();
free(in_progress_codelet_name);
in_progress_codelet_name = NULL;
in_progress_invocation = -1;


if (kill_after_dump) {
debug_print("[tracee %d] Single capture : terminating tracer and tracee\n", getpid());
abort();
}
else {
pid_t parent = getppid();
debug_print("[tracee %d] Multi capture : spawn new tracer and resume exec\n", getpid());
// Send a fake SIGABRT so the tracer frees us & terminates itself
kill(parent, 6);

// Directly spawn a new tracer to record hotpages map
fork_tracee();
}

}
2 changes: 1 addition & 1 deletion src/memory_dump/tracee.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ void dump(char *loop_name, char *invocations_str, int arg_count, ...);

/* after_dump: terminates capture of a region of interest. must be called
at the end of the function to be captured */
void after_dump(void);
void after_dump(char *loop_name);

/* mtrace_active: true when the memory protection hooks in hooks.c are
* active */
Expand Down

0 comments on commit 4659339

Please sign in to comment.