void acc_tuner_generate_performance_table( float (*eval_performance)(void *, long, long) ) { assert(acc_tuner->num_devices == 1); size_t i, j; char * perf_table_content_prefix = "run_id, device INT, version_id INT, gang INT, worker INT"; char * perf_table_content_suffix = ", gflops FLOAT"; size_t size = strlen(perf_table_content_prefix) + strlen(perf_table_content_suffix); for (i = 0; i < acc_tuner->data_params->num_params; i++) size += strlen(acc_tuner->data_params->name_params[i]) + strlen(acc_sqlite_type_string(acc_tuner->data_params->type_params[i])) + 3; char * perf_table_content = malloc(size * sizeof(char)); perf_table_content[0] = '\0'; strcat(perf_table_content, perf_table_content_prefix); for (i = 0; i < acc_tuner->data_params->num_params; i++) { strcat(perf_table_content, ", "); strcat(perf_table_content, acc_tuner->data_params->name_params[i]); strcat(perf_table_content, " "); strcat(perf_table_content, acc_sqlite_type_string(acc_tuner->data_params->type_params[i])); } strcat(perf_table_content, perf_table_content_suffix); acc_sqlite_create_table(acc_tuner->versions_db, "Performances", perf_table_content); char * runs_conds[1] = {"executed == '3'"}; size_t entry_size; void * run_entries; size_t num_fields; char ** field_names; enum acc_sqlite_type_e * field_types; size_t * field_sizes; size_t * field_offsets; size_t num_entries = acc_sqlite_read_run_table( acc_profiler->db_file, acc_tuner->num_devices, acc_tuner->data_params, 1, runs_conds, &entry_size, &run_entries, &num_fields, &field_names, &field_types, &field_sizes, &field_offsets, NULL ); size_t query_length = 0; char * query = NULL; size_t num_query = 0; #pragma omp parallel shared(acc_profiler, acc_tuner, entry_size, run_entries, num_fields, field_names, field_types, field_sizes, field_offsets, num_entries) \ private(i,j) firstprivate(query_length, query, num_query) { #pragma omp for for (i = 0; i < num_entries; i++) { size_t run_id = *(size_t *)(run_entries + i * entry_size + field_offsets[0]); char run_id_cond[20]; sprintf(run_id_cond, "run_id == '%zd'", run_id); char * events_conds[1] = {run_id_cond}; struct acc_sqlite_event_entry_t * event_entries; size_t num_events = 0; #pragma omp critical { num_events = acc_sqlite_read_table( acc_profiler->db_file, "Events", 1, events_conds, event_entry_num_fields, event_entry_field_names, event_entry_field_types, event_entry_field_sizes, event_entry_field_offsets, sizeof(struct acc_sqlite_event_entry_t), (void**)&event_entries ); } if (num_events < 1) { printf("No event for run #%d.\n", run_id); assert(0); } size_t device_id = event_entries[0].device_id; size_t version_id = *(size_t *)(run_entries + i * entry_size + field_offsets[1]); size_t gang = *(size_t *)(run_entries + i * entry_size + field_offsets[3]); size_t worker = *(size_t *)(run_entries + i * entry_size + field_offsets[4]); float gflops = 0; for (j = 0; j < num_events; j++) { float tmp = (*eval_performance)(run_entries + i * entry_size + field_offsets[6], event_entries[j].cl_profiling_command_start, event_entries[j].cl_profiling_command_end); if (tmp > gflops) gflops = tmp; } char run_id_str[32]; sprintf(run_id_str, "'%zd', ", run_id); char device_id_str[32]; sprintf(device_id_str, "'%zd', ", device_id); char version_id_str[32]; sprintf(version_id_str, "'%zd', ", version_id); char gang_str[32]; sprintf(gang_str, "'%zd', ", gang); char worker_str[32]; sprintf(worker_str, "'%zd', ", worker); char * params_str = malloc(32 * acc_tuner->data_params->num_params * sizeof(char)); params_str[0] = '\0'; for (j = 0; j < acc_tuner->data_params->num_params; j++) { char tmp[32]; switch (acc_tuner->data_params->type_params[j]) { case e_sqlite_int: sprintf(tmp, "'%zd', ", *(size_t *)(run_entries + i * entry_size + field_offsets[6 + j])); break; default: assert(0); } strcat(params_str, tmp); } char gflops_str[32]; sprintf(gflops_str, "'%f'", gflops); query_length += strlen(run_id_str) + strlen(device_id_str) + strlen(version_id_str) + strlen(gang_str) + strlen(worker_str) + strlen(params_str) + strlen(gflops_str) + 38; char * new_query = realloc(query, query_length * sizeof(char)); if (query == NULL) new_query[0] = '\0'; query = new_query; num_query++; strcat(query, "INSERT INTO Performances VALUES ( "); strcat(query, run_id_str); strcat(query, device_id_str); strcat(query, version_id_str); strcat(query, gang_str); strcat(query, worker_str); strcat(query, params_str); strcat(query, gflops_str); strcat(query, " );"); /* if (num_query > 1000) { char * err_msg; int status; #pragma omp critical { status = sqlite3_exec (acc_tuner->versions_db, query, NULL, 0, &err_msg); } assert(status == SQLITE_OK); query_length = 0; free(query); query = NULL; num_query = 0; } */ free(params_str); } if (num_query > 0) { char * err_msg; int status; #pragma omp critical { status = sqlite3_exec (acc_tuner->versions_db, query, NULL, 0, &err_msg); } assert(status == SQLITE_OK); query_length = 0; free(query); query = NULL; num_query = 0; } } acc_sqlite_clean_run_table_read(acc_tuner->num_devices, field_names, field_types, field_sizes, field_offsets); free(run_entries); }
int acc_sqlite_read_run_table( sqlite3 * db, size_t num_devices, struct acc_tuner_data_params_desc_t_ * data_params, size_t num_conds, char ** conds, size_t * entry_size, void ** run_entries, size_t * num_fields, char *** field_names, enum acc_sqlite_type_e ** field_types, size_t ** field_sizes, size_t ** field_offsets, char * run_id_str ) { size_t i; size_t num_dev_fields = ((num_devices == 1) ? 5 : (num_devices * 6)) + 1; *num_fields = num_dev_fields + data_params->num_params; *field_names = malloc(*num_fields * sizeof(char *)); *field_types = malloc(*num_fields * sizeof(enum acc_sqlite_type_e)); *field_sizes = malloc(*num_fields * sizeof(size_t)); *field_offsets = malloc(*num_fields * sizeof(size_t)); if (run_id_str == NULL) (*field_names) [0] = "rowid"; else (*field_names) [0] = run_id_str; (*field_types) [0] = e_sqlite_int; (*field_sizes) [0] = sizeof(size_t); (*field_offsets)[0] = 0; if (num_devices == 1) { (*field_names) [1] = "version_id"; (*field_types) [1] = e_sqlite_int; (*field_sizes) [1] = sizeof(size_t); (*field_offsets)[1] = (*field_offsets)[0] + (*field_sizes)[0];; (*field_names) [2] = "acc_device_type"; (*field_types) [2] = e_sqlite_text; (*field_sizes) [2] = sizeof(char[40]); (*field_offsets)[2] = (*field_offsets)[1] + (*field_sizes)[1]; (*field_names) [3] = "gang"; (*field_types) [3] = e_sqlite_int; (*field_sizes) [3] = sizeof(size_t); (*field_offsets)[3] = (*field_offsets)[2] + (*field_sizes)[2]; (*field_names) [4] = "worker"; (*field_types) [4] = e_sqlite_int; (*field_sizes) [4] = sizeof(size_t); (*field_offsets)[4] = (*field_offsets)[3] + (*field_sizes)[3]; (*field_names) [5] = "vector"; (*field_types) [5] = e_sqlite_int; (*field_sizes) [5] = sizeof(size_t); (*field_offsets)[5] = (*field_offsets)[4] + (*field_sizes)[4]; } else { size_t offset = 0; for (i = 0; i < num_devices; i++) { (*field_names) [6 * i + 1] = malloc(14 * sizeof(char)); sprintf((*field_names)[6 * i + 1], "version_id_%zd", i); (*field_types) [6 * i + 1] = e_sqlite_int; (*field_sizes) [6 * i + 1] = sizeof(size_t); (*field_offsets)[6 * i + 1] = offset; offset += (*field_sizes)[6 * i + 1]; (*field_names) [6 * i + 2] = malloc(19 * sizeof(char)); sprintf((*field_names)[6 * i + 2], "acc_device_type_%zd", i); (*field_types) [6 * i + 2] = e_sqlite_text; (*field_sizes) [6 * i + 2] = sizeof(char[40]); (*field_offsets)[6 * i + 2] = offset; offset += (*field_sizes)[6 * i + 2]; (*field_names) [6 * i + 3] = malloc(8 * sizeof(char)); sprintf((*field_names)[6 * i + 3], "gang_%zd", i); (*field_types) [6 * i + 3] = e_sqlite_int; (*field_sizes) [6 * i + 3] = sizeof(size_t); (*field_offsets)[6 * i + 3] = offset; offset += (*field_sizes)[6 * i + 3]; (*field_names) [6 * i + 4] = malloc(10 * sizeof(char)); sprintf((*field_names)[6 * i + 4], "worker_%zd", i); (*field_types) [6 * i + 4] = e_sqlite_int; (*field_sizes) [6 * i + 4] = sizeof(size_t); (*field_offsets)[6 * i + 4] = offset; offset += (*field_sizes)[6 * i + 4]; (*field_names) [6 * i + 5] = malloc(10 * sizeof(char)); sprintf((*field_names)[6 * i + 5], "vector_%zd", i); (*field_types) [6 * i + 5] = e_sqlite_int; (*field_sizes) [6 * i + 5] = sizeof(size_t); (*field_offsets)[6 * i + 5] = offset; offset += (*field_sizes)[6 * i + 5]; (*field_names) [6 * i + 6] = malloc(11 * sizeof(char)); sprintf((*field_names)[6 * i + 6], "portion_%zd", i); (*field_types) [6 * i + 6] = e_sqlite_int; (*field_sizes) [6 * i + 6] = sizeof(size_t); (*field_offsets)[6 * i + 6] = offset; offset += (*field_sizes)[6 * i + 6]; } } for (i = 0; i < data_params->num_params; i++) { (*field_names) [num_dev_fields + i] = data_params->name_params[i]; (*field_types) [num_dev_fields + i] = data_params->type_params[i]; (*field_sizes) [num_dev_fields + i] = acc_sqlite_type_size(data_params->type_params[i]); (*field_offsets)[num_dev_fields + i] = (*field_offsets)[num_dev_fields + i - 1] + (*field_sizes)[num_dev_fields + i - 1]; } *entry_size = 0; for (i = 0; i < *num_fields; i++) *entry_size += (*field_sizes)[i]; return acc_sqlite_read_table( db, "Runs", num_conds, conds, *num_fields, *field_names, *field_types, *field_sizes, *field_offsets, *entry_size, run_entries ); }