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);
}
Ejemplo n.º 2
0
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
  );
}