-
Notifications
You must be signed in to change notification settings - Fork 62
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add initial MPI_T-like profiling support in Mercury #350
base: master
Are you sure you want to change the base?
Changes from 7 commits
6d26e00
16c6512
05b796b
a7e5988
0948b0f
efa77e9
237c6ee
61df90a
a784eca
7060882
c8d73b9
b7fdd9b
c174d8d
6dbd7c2
e168c03
ce29621
8ee302f
c223544
d607861
329dcba
7e46221
5c62fd2
7573858
f31582b
3b9768b
8a11087
8a05135
1fa40af
97203e3
73688a2
9457bd6
fb148c8
4e39c83
e96b7a0
f69ddad
d5f7c1a
ace64be
c0e2321
a55bc1e
d98a378
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,281 @@ | ||
/* | ||
* Copyright (C) 2013-2020 Argonne National Laboratory, Department of Energy, | ||
* UChicago Argonne, LLC and The HDF Group. | ||
* All rights reserved. | ||
* | ||
* The full copyright notice, including terms governing use, modification, | ||
* and redistribution, is contained in the COPYING file that can be | ||
* found at the root of the source code distribution tree. | ||
*/ | ||
|
||
#include "mercury.h" | ||
#include "mercury_bulk.h" | ||
#include "mercury_core.h" | ||
#include "mercury_private.h" | ||
#include "mercury_error.h" | ||
|
||
#include "mercury_atomic.h" | ||
#include "mercury_types.h" | ||
#include "mercury_prof_interface.h" | ||
#include "mercury_prof_pvar_impl.h" | ||
|
||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <assert.h> | ||
|
||
/************************************/ | ||
/* Local Type and Struct Definition */ | ||
/************************************/ | ||
|
||
/* HG profiling PVAR handle object concrete definition */ | ||
struct hg_prof_pvar_handle { | ||
hg_prof_class_t pvar_class; /* PVAR class */ | ||
hg_prof_datatype_t pvar_datatype; /* PVAR datatype */ | ||
hg_prof_bind_t pvar_bind; /* PVAR binding */ | ||
int continuous; /* is PVAR continuous or not */ | ||
void * addr; /* actual address of PVAR */ | ||
int is_started; /* if continuous, has PVAR been started? */ | ||
int count; /* number of values associated with PVAR */ | ||
char name[128]; /* PVAR name */ | ||
char description[128]; /* PVAR description */ | ||
}; | ||
|
||
/* HG profiling session object concrete definition */ | ||
struct hg_prof_pvar_session { | ||
hg_prof_pvar_handle_t * pvar_handle_array; /* PVAR handle array */ | ||
int is_initialized; /* Is profiling initialized */ | ||
}; | ||
|
||
/* HG class */ | ||
struct hg_private_class { | ||
struct hg_class hg_class; /* Must remain as first field */ | ||
int hg_prof_is_initialized; /* Is profiling initialized */ | ||
int num_pvars; /* No of PVARs currently supported */ | ||
hg_prof_pvar_session_t session; /* Is profiling initialized on the session */ | ||
}; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe I am missing something but you should have a |
||
|
||
/*******************/ | ||
/* Local Variables */ | ||
/*******************/ | ||
|
||
/*---------------------------------------------------------------------------*/ | ||
static void | ||
hg_prof_set_is_initialized(struct hg_private_class * hg_private_class) | ||
{ | ||
hg_private_class->hg_prof_is_initialized = 1; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just a detail but instead of using 1 or 0, there are HG_TRUE and HG_FALSE macros |
||
|
||
/*---------------------------------------------------------------------------*/ | ||
static int | ||
hg_prof_get_is_initialized(struct hg_private_class * hg_private_class) { | ||
return hg_private_class->hg_prof_is_initialized; | ||
} | ||
|
||
/*---------------------------------------------------------------------------*/ | ||
static void | ||
hg_prof_set_session_is_initialized(struct hg_prof_pvar_session * session) | ||
{ | ||
session->is_initialized = 1; | ||
} | ||
|
||
/*---------------------------------------------------------------------------*/ | ||
static int | ||
hg_prof_get_session_is_initialized(struct hg_prof_pvar_session * session) { | ||
return session->is_initialized; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here, you could return an hg_bool_t instead. |
||
|
||
/*---------------------------------------------------------------------------*/ | ||
hg_return_t | ||
HG_Prof_init(hg_class_t *hg_class) { | ||
|
||
struct hg_private_class *hg_private_class = (struct hg_private_class *)(hg_class); | ||
|
||
hg_prof_set_is_initialized(hg_private_class); | ||
hg_private_class->num_pvars = NUM_PVARS; | ||
hg_private_class->session = NULL; | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think you are allowed to do that here :) HG_Prof_init() should return a new hg_prof_class_t * so I would expect you to malloc a new struct hg_prof_class in that routine, fill it and return it. |
||
return HG_SUCCESS; | ||
} | ||
|
||
/*---------------------------------------------------------------------------*/ | ||
hg_return_t | ||
HG_Prof_finalize(hg_class_t *hg_class) { | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here instead it should take an hg_prof_class_t * |
||
struct hg_private_class *hg_private_class = (struct hg_private_class *)(hg_class); | ||
|
||
if(hg_prof_get_is_initialized(hg_private_class)) { | ||
hg_prof_set_is_initialized(hg_private_class); | ||
hg_private_class->session = NULL; | ||
} | ||
|
||
return HG_SUCCESS; | ||
} | ||
|
||
/*---------------------------------------------------------------------------*/ | ||
int | ||
HG_Prof_pvar_get_num(hg_class_t *hg_class) { | ||
struct hg_private_class *hg_private_class = (struct hg_private_class *)(hg_class); | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here and following routines |
||
if(hg_prof_get_is_initialized(hg_private_class)) { | ||
return hg_private_class->num_pvars; | ||
} else { | ||
return 0; | ||
} | ||
} | ||
|
||
/*---------------------------------------------------------------------------*/ | ||
hg_return_t | ||
HG_Prof_pvar_get_info(hg_class_t *hg_class, int pvar_index, char *name, int *name_len, hg_prof_class_t *var_class, hg_prof_datatype_t *datatype, char *desc, int *desc_len, hg_prof_bind_t *bind, int *continuous) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So that means hg_prof_class_t becomes hg_prof_var_class_t ? |
||
|
||
struct hg_private_class *hg_private_class = (struct hg_private_class *)(hg_class); | ||
|
||
if(!hg_prof_get_is_initialized(hg_private_class)) | ||
return HG_NA_ERROR; | ||
|
||
assert(pvar_index < NUM_PVARS); | ||
|
||
unsigned int key = pvar_index; | ||
hg_prof_pvar_data_t * val; | ||
|
||
/* Lookup the internal PVAR hash table to gather information about this PVAR */ | ||
val = hg_prof_pvar_table_lookup(key); | ||
strcpy(name, (*val).name); | ||
*name_len = strlen(name); | ||
strcpy(desc, (*val).description); | ||
*desc_len = strlen(desc); | ||
*var_class = (*val).pvar_class; | ||
*datatype = (*val).pvar_datatype; | ||
*bind = (*val).pvar_bind; | ||
*continuous = (*val).continuous; | ||
|
||
return HG_SUCCESS; | ||
} | ||
|
||
/*---------------------------------------------------------------------------*/ | ||
hg_return_t | ||
HG_Prof_pvar_session_create(hg_class_t *hg_class, hg_prof_pvar_session_t *session) { | ||
|
||
struct hg_private_class *hg_private_class = (struct hg_private_class *)(hg_class); | ||
|
||
if(!hg_prof_get_is_initialized(hg_private_class)) | ||
return HG_NA_ERROR; | ||
|
||
(*session) = (hg_prof_pvar_session_t)malloc(sizeof(struct hg_prof_pvar_session)); | ||
(*session)->pvar_handle_array = (hg_prof_pvar_handle_t *)malloc(sizeof(hg_prof_pvar_handle_t)*NUM_PVARS); | ||
hg_private_class->session = (*session); | ||
|
||
hg_prof_set_session_is_initialized((*session)); | ||
|
||
return HG_SUCCESS; | ||
} | ||
|
||
/*---------------------------------------------------------------------------*/ | ||
hg_return_t | ||
HG_Prof_pvar_session_destroy(hg_class_t *hg_class, hg_prof_pvar_session_t *session) { | ||
|
||
struct hg_private_class *hg_private_class = (struct hg_private_class *)(hg_class); | ||
|
||
if(!hg_prof_get_is_initialized(hg_private_class)) | ||
return HG_NA_ERROR; | ||
|
||
free((*session)->pvar_handle_array); | ||
free((*session)); | ||
hg_private_class->session = NULL; | ||
|
||
return HG_SUCCESS; | ||
} | ||
/*---------------------------------------------------------------------------*/ | ||
hg_return_t | ||
HG_Prof_pvar_handle_alloc(hg_prof_pvar_session_t session, int pvar_index, void *obj_handle, hg_prof_pvar_handle_t *handle, int *count) { | ||
|
||
if(!hg_prof_get_session_is_initialized(session)) | ||
return HG_NA_ERROR; | ||
|
||
/* Only supporting a null bind type at the moment */ | ||
assert(obj_handle == NULL); | ||
|
||
struct hg_prof_pvar_session s = *session; | ||
unsigned int key = pvar_index; | ||
hg_prof_pvar_data_t * val; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please keep declarations at beginning of blocks |
||
|
||
s.pvar_handle_array[pvar_index] = (hg_prof_pvar_handle_t)malloc(sizeof(struct hg_prof_pvar_handle)); | ||
val = hg_prof_pvar_table_lookup(key); | ||
|
||
/* Copy out information from the internal PVAR hash table */ | ||
(*s.pvar_handle_array[pvar_index]).pvar_class = (*val).pvar_class; | ||
(*s.pvar_handle_array[pvar_index]).pvar_datatype = (*val).pvar_datatype; | ||
(*s.pvar_handle_array[pvar_index]).pvar_bind = (*val).pvar_bind; | ||
(*s.pvar_handle_array[pvar_index]).continuous = (*val).continuous; | ||
(*s.pvar_handle_array[pvar_index]).is_started = 0; | ||
(*s.pvar_handle_array[pvar_index]).addr = (*val).addr; | ||
if((*val).continuous) | ||
(*s.pvar_handle_array[pvar_index]).is_started = 1; | ||
strcpy((*s.pvar_handle_array[pvar_index]).name, (*val).name); | ||
strcpy((*s.pvar_handle_array[pvar_index]).description, (*val).description); | ||
*count = (*val).count; | ||
|
||
/* Return handle */ | ||
*handle = s.pvar_handle_array[pvar_index]; | ||
|
||
return HG_SUCCESS; | ||
} | ||
|
||
/*---------------------------------------------------------------------------*/ | ||
hg_return_t | ||
HG_Prof_pvar_handle_free(hg_prof_pvar_session_t session, int pvar_index, hg_prof_pvar_handle_t *handle) { | ||
|
||
if(!hg_prof_get_session_is_initialized(session)) | ||
return HG_NA_ERROR; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. that seems like the wrong error code :) HG_NA_ERROR means it's an NA layer error so maybe just HG_INVALID_ARG? |
||
|
||
|
||
struct hg_prof_pvar_session s = *session; | ||
assert(s.pvar_handle_array[pvar_index] == *handle); | ||
free(s.pvar_handle_array[pvar_index]); | ||
s.pvar_handle_array[pvar_index] = NULL; | ||
*handle = NULL; | ||
|
||
return HG_SUCCESS; | ||
} | ||
|
||
/*---------------------------------------------------------------------------*/ | ||
hg_return_t | ||
HG_Prof_pvar_start(hg_prof_pvar_session_t session, hg_prof_pvar_handle_t handle) { | ||
if(!hg_prof_get_session_is_initialized(session)) | ||
return HG_NA_ERROR; | ||
|
||
if (!(*handle).continuous && !((*handle).is_started)) | ||
(*handle).is_started = 1; | ||
return HG_SUCCESS; | ||
} | ||
|
||
/*---------------------------------------------------------------------------*/ | ||
hg_return_t | ||
HG_Prof_pvar_stop(hg_prof_pvar_session_t session, hg_prof_pvar_handle_t handle) { | ||
if(!hg_prof_get_session_is_initialized(session)) | ||
return HG_NA_ERROR; | ||
|
||
if (!(*handle).continuous && ((*handle).is_started)) | ||
(*handle).is_started = 0; | ||
return HG_SUCCESS; | ||
} | ||
|
||
/*---------------------------------------------------------------------------*/ | ||
hg_return_t | ||
HG_Prof_pvar_read(hg_prof_pvar_session_t session, hg_prof_pvar_handle_t handle, void *buf) { | ||
if(!hg_prof_get_session_is_initialized(session)) | ||
return HG_NA_ERROR; | ||
|
||
/* Assert first that handle belongs to the session provided. NOT DOING THIS HERE FOR NOW */ | ||
struct hg_prof_pvar_handle h = (*handle); | ||
switch(h.pvar_datatype) { | ||
case HG_UINT: | ||
/*for(int i = 0; i < h.count; h++)*/ /* Need to support PVAR arrays, just a placeholder that assumes PVAR count is 1 */ | ||
*((unsigned int *)buf) = *((unsigned int *)h.addr); | ||
break; | ||
case HG_DOUBLE: | ||
*((double *)buf) = *((double *)h.addr); | ||
break; | ||
} | ||
return HG_SUCCESS; | ||
} | ||
/*---------------------------------------------------------------------------*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As a general comment I think it would be good to see if/how we can avoid declaring global variables.