text: #include "viterbi.h"
  #include "support.h"
  #include <string.h>
  
  int INPUT_SIZE = sizeof(struct bench_args_t);
  
  void run_benchmark( void *vargs, cl_context& context, cl_command_queue& commands, cl_program& program, cl_kernel& kernel ) {
    struct bench_args_t *args = (struct bench_args_t *)vargs;
    // Create device buffers
    //
    static unsigned *obs_buffer = (unsigned int*)clSVMAllocAltera(context, 0, sizeof(args->obs), 1024); 
    static unsigned *init_buffer = (unsigned int*)clSVMAllocAltera(context, 0, sizeof(args->init), 1024); 
    static unsigned *transition_buffer = (unsigned int*)clSVMAllocAltera(context, 0, sizeof(args->transition), 1024); 
    static unsigned *emission_buffer = (unsigned int*)clSVMAllocAltera(context, 0, sizeof(args->emission), 1024); 
    static unsigned *path_buffer = (unsigned int*)clSVMAllocAltera(context, 0, sizeof(args->path), 1024); 
  
    // Write our data set into device buffers  
    //
    memcpy(obs_buffer, args->obs, sizeof(args->obs));
    memcpy(init_buffer, args->init, sizeof(args->init));
    memcpy(transition_buffer, args->transition, sizeof(args->transition));
    memcpy(emission_buffer, args->emission, sizeof(args->emission));
    memcpy(path_buffer, args->path, sizeof(args->path));
      
    // Set the arguments to our compute kernel
    //
    int status;
    status = clSetKernelArgSVMPointerAltera(kernel, 0, (void*)obs_buffer);
    status |= clSetKernelArgSVMPointerAltera(kernel, 1, (void*)init_buffer);
    status |= clSetKernelArgSVMPointerAltera(kernel, 2, (void*)transition_buffer);
    status |= clSetKernelArgSVMPointerAltera(kernel, 3, (void*)emission_buffer);
    status |= clSetKernelArgSVMPointerAltera(kernel, 4, (void*)path_buffer);
    if(status != CL_SUCCESS) {
      dump_error("Failed set args.", status);
      exit(1);
    }
  
    // Execute the kernel over the entire range of our 1d input data set
    // using the maximum number of work group items for this device
    //
  
  #ifdef OPENCL_KERNEL
    status = clEnqueueTask(commands, kernel, 0, NULL, NULL);
  #else
    printf("Error: C kernel is not currently supported!\n");
    exit(1);
  #endif
    if (status)
    {
      printf("Error: Failed to execute kernel! %d\n", status);
      printf("Test failed\n");
      exit(1);
    }
    clFinish(commands);
  
    // Read back the results from the device to verify the output
    //
    memcpy(args->path, path_buffer, sizeof(args->path));
  }
  
  /* Input format:
  %% Section 1
  tok_t[N_OBS]: observation vector
  %% Section 2
  prob_t[N_STATES]: initial state probabilities
  %% Section 3
  prob_t[N_STATES*N_STATES]: transition matrix
  %% Section 4
  prob_t[N_STATES*N_TOKENS]: emission matrix
  */
  
  void input_to_data(int fd, void *vdata) {
    struct bench_args_t *data = (struct bench_args_t *)vdata;
    char *p, *s;
    // Zero-out everything.
    memset(vdata,0,sizeof(struct bench_args_t));
    // Load input string
    p = readfile(fd);
  
    s = find_section_start(p,1);
    parse_uint8_t_array(s, data->obs, N_OBS);
  
    s = find_section_start(p,2);
    STAC(parse_,TYPE,_array)(s, data->init, N_STATES);
  
    s = find_section_start(p,3);
    STAC(parse_,TYPE,_array)(s, data->transition, N_STATES*N_STATES);
  
    s = find_section_start(p,4);
    STAC(parse_,TYPE,_array)(s, data->emission, N_STATES*N_TOKENS);
  }
  
  void data_to_input(int fd, void *vdata) {
    struct bench_args_t *data = (struct bench_args_t *)vdata;
  
    write_section_header(fd);
    write_uint8_t_array(fd, data->obs, N_OBS);
  
    write_section_header(fd);
    STAC(write_,TYPE,_array)(fd, data->init, N_STATES);
  
    write_section_header(fd);
    STAC(write_,TYPE,_array)(fd, data->transition, N_STATES*N_STATES);
  
    write_section_header(fd);
    STAC(write_,TYPE,_array)(fd, data->emission, N_STATES*N_TOKENS);
  }
  
  /* Output format:
  %% Section 1
  uint8_t[N_OBS]: most likely state chain
  */
  
  void output_to_data(int fd, void *vdata) {
    struct bench_args_t *data = (struct bench_args_t *)vdata;
    char *p, *s;
    // Zero-out everything.
    memset(vdata,0,sizeof(struct bench_args_t));
    // Load input string
    p = readfile(fd);
  
    s = find_section_start(p,1);
    parse_uint8_t_array(s, data->path, N_OBS);
  }
  
  void data_to_output(int fd, void *vdata) {
    struct bench_args_t *data = (struct bench_args_t *)vdata;
  
    write_section_header(fd);
    write_uint8_t_array(fd, data->path, N_OBS);
  }
  
  int check_data( void *vdata, void *vref ) {
    struct bench_args_t *data = (struct bench_args_t *)vdata;
    struct bench_args_t *ref = (struct bench_args_t *)vref;
    int has_errors = 0;
    int i;
  
    for(i=0; i<N_OBS; i++) {
      has_errors |= (data->path[i]!=ref->path[i]);
    }
  
    // Return true if it's correct.
    return !has_errors;
  }
  