OverviewFilesCommitsIssuesDocsReleasesPeers

opencog-CompactHash / HashFactory / CLHash_Utilities.c

469 lines · c ref:
/* Copyright 2013-14.  Los Alamos National Security, LLC. This material was produced
 * under U.S. Government contract DE-AC52-06NA25396 for Los Alamos National 
 * Laboratory (LANL), which is operated by Los Alamos National Security, LLC
 * for the U.S. Department of Energy. The U.S. Government has rights to use,
 * reproduce, and distribute this software.  NEITHER THE GOVERNMENT NOR LOS
 * ALAMOS NATIONAL SECURITY, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
 * ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE.  If software is modified
 * to produce derivative works, such modified software should be clearly marked,
 * so as not to confuse it with the version available from LANL.   
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy
 * of the License at 
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed
 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
 * CONDITIONS OF ANY KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 *
 * Under this license, it is required to include a reference to this work. We
 * request that each derivative work contain a reference to LANL Copyright 
 * Disclosure C14043/LA-CC-14-003 so that this work's impact can be roughly
 * measured. In addition, it is requested that a modifier is included as in
 * the following example:
 *
 * //<Uses | improves on | modified from> LANL Copyright Disclosure C14043/LA-CC-14-003
 *
 * This is LANL Copyright Disclosure C14043/LA-CC-14-003
 */

/**
 * @file   CLHash_Utilities.c
 * @author Ahrens/Robey -- rewritten for distribution
 * @date   Sun Aug 4 2013 
 */

#define _XOPEN_SOURCE 500

#include <execinfo.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "CLHash_Utilities.h"


//#ifdef HAVE_CONFIG_H
//#include "config.h"
//#endif

#ifdef HAVE_OPENCL
#ifdef __APPLE_CC__
#include <OpenCL/OpenCL.h>
#else
#include <CL/cl.h>
#endif

#else
int clGetPlatformIDs(uint nentries, int *platforms, uint *nplatforms) { return 0; }
int clGetDeviceIDs(int platform, int device_type, uint nentries, int *devices, uint *ndevices) { return 0; } 
int clGetPlatformInfo(int platform, int param_name, size_t size, void *value, size_t *size_ret) { return 0; } 
int clGetDeviceInfo(int device, int param_name, size_t size, void *value, size_t *size_ret) { return 0; } 
int clCreateContext(int *properties, uint ndevices, const int *devices, void *notify, void *user_data, int *errcode_ret) { return 0; }
int clCreateCommandQueue(int context, int device, int properties, int *errcode_ret) { return 0; }
int clCreateProgramWithSource(int context, uint count, const char **strings, const size_t *lengths, int *errcode_ret) { return 0; }
int clBuildProgram(int program, uint ndevices, const int *device_list, const char *options, void *notify, void *user_data) { return 0; }
int clGetProgramBuildInfo(int program, int devices, int param_name, size_t size, void *value, size_t *size_ret) { return 0; }

#define CL_SUCCESS                           0
#define CL_PROGRAM_LOG                       0
#define CL_PROGRAM_BUILD_LOG                 0
#define CL_DEVICE_TYPE_GPU                   0
#define CL_DEVICE_TYPE_CPU                   0
#define CL_DEVICE_TYPE_ACCELERATOR           0
#define CL_DEVICE_NAME                       0
#define CL_DEVICE_VENDOR                     0
#define CL_PLATFORM_NAME                     0
#define CL_PLATFORM_VENDOR                   0
#define CL_PLATFORM_VERSION                  0
#define CL_QUEUE_PROFILING_ENABLE            0

#define CL_DEVICE_NOT_FOUND                 -1
#define CL_DEVICE_NOT_AVAILABLE             -2
#define CL_COMPILER_NOT_AVAILABLE           -3
#define CL_MEM_OBJECT_ALLOCATION_FAILURE    -4
#define CL_OUT_OF_RESOURCES                 -5
#define CL_OUT_OF_HOST_MEMORY               -6
#define CL_PROFILING_INFO_NOT_AVAILABLE     -7
#define CL_MEM_COPY_OVERLAP                 -8
#define CL_IMAGE_FORMAT_MISMATCH            -9
#define CL_IMAGE_FORMAT_NOT_SUPPORTED       -10
#define CL_BUILD_PROGRAM_FAILURE            -11
#define CL_MAP_FAILURE                      -12
#define CL_INVALID_VALUE                    -30
#define CL_INVALID_DEVICE_TYPE              -31
#define CL_INVALID_PLATFORM                 -32
#define CL_INVALID_DEVICE                   -33
#define CL_INVALID_CONTEXT                  -34
#define CL_INVALID_QUEUE_PROPERTIES         -35
#define CL_INVALID_COMMAND_QUEUE            -36
#define CL_INVALID_HOST_PTR                 -37
#define CL_INVALID_MEM_OBJECT               -38
#define CL_INVALID_IMAGE_FORMAT_DESCRIPTOR  -39
#define CL_INVALID_IMAGE_SIZE               -40
#define CL_INVALID_SAMPLER                  -41
#define CL_INVALID_BINARY                   -42
#define CL_INVALID_BUILD_OPTIONS            -43
#define CL_INVALID_PROGRAM                  -44
#define CL_INVALID_PROGRAM_EXECUTABLE       -45
#define CL_INVALID_KERNEL_NAME              -46
#define CL_INVALID_KERNEL_DEFINITION        -47
#define CL_INVALID_KERNEL                   -48
#define CL_INVALID_ARG_INDEX                -49
#define CL_INVALID_ARG_VALUE                -50
#define CL_INVALID_ARG_SIZE                 -51
#define CL_INVALID_KERNEL_ARGS              -52
#define CL_INVALID_WORK_DIMENSION           -53
#define CL_INVALID_WORK_GROUP_SIZE          -54
#define CL_INVALID_WORK_ITEM_SIZE           -55
#define CL_INVALID_GLOBAL_OFFSET            -56
#define CL_INVALID_EVENT_WAIT_LIST          -57
#define CL_INVALID_EVENT                    -58
#define CL_INVALID_OPERATION                -59
#define CL_INVALID_GL_OBJECT                -60
#define CL_INVALID_BUFFER_SIZE              -61
#define CL_INVALID_MIP_LEVEL                -62
#endif

#ifndef DEBUG
#define DEBUG 0
#endif

typedef unsigned int uint;

char *program_name = NULL;

void CLHash_Init(const char *program_name_in)
{
   program_name = strdup(program_name_in);
}

/* Find a GPU or CPU associated with the first available platform */
void CLHash_Utilities_CreateContext_p(cl_context *context, cl_command_queue *command_queue, const char *file , int line) {

   uint num_platforms;
   cl_platform_id *platforms;
   cl_device_id device;
   int err;

   /* Get all available platforms */
   err = clGetPlatformIDs(0, NULL, &num_platforms);
   CLHash_Utilities_HandleError(err, "CLHash_Utilities_CreateContext", "clGetPlatformIDs");
   platforms = (cl_platform_id *)malloc(num_platforms*sizeof(cl_platform_id));
   /* Identify a platform */
   err = clGetPlatformIDs(num_platforms, platforms, NULL);
   CLHash_Utilities_HandleError(err, "CLHash_Utilities_CreateContext", "clGetPlatformIDs");

   if (DEBUG == 1) {
     char info[1024];
     for (int iplatform=0; iplatform<num_platforms; iplatform++){
       printf("  Platform %d:\n",iplatform+1);

       //clGetPlatformInfo(platforms[iplatform],CL_PLATFORM_PROFILE,   1024L,info,0);
       //printf("    CL_PLATFORM_PROFILE    : %s\n",info);

       clGetPlatformInfo(platforms[iplatform],CL_PLATFORM_VERSION,   1024L,info,0);
       printf("    CL_PLATFORM_VERSION    : %s\n",info);

       clGetPlatformInfo(platforms[iplatform],CL_PLATFORM_NAME,      1024L,info,0);
       printf("    CL_PLATFORM_NAME       : %s\n",info);

       clGetPlatformInfo(platforms[iplatform],CL_PLATFORM_VENDOR,    1024L,info,0);
       printf("    CL_PLATFORM_VENDOR     : %s\n",info);

       //clGetPlatformInfo(platforms[iplatform],CL_PLATFORM_EXTENSIONS,1024L,info,0);
       // printf("    CL_PLATFORM_EXTENSIONS : %s\n",info);
     }
   }

   /* Access a device */
   for (int iplatform=0; iplatform<num_platforms; iplatform++){
     err = clGetDeviceIDs(platforms[iplatform], CL_DEVICE_TYPE_GPU, 1, &device, NULL);
     if(err != CL_DEVICE_NOT_FOUND){
       break;
     }
   }
   if(err == CL_DEVICE_NOT_FOUND){
     for (int iplatform=0; iplatform<num_platforms; iplatform++){
       err = clGetDeviceIDs(platforms[iplatform], CL_DEVICE_TYPE_ACCELERATOR, 1, &device, NULL);
       if(err != CL_DEVICE_NOT_FOUND){
         break;
       }
     }
     if(err == CL_DEVICE_NOT_FOUND){
       for (int iplatform=0; iplatform<num_platforms; iplatform++){
         err = clGetDeviceIDs(platforms[iplatform], CL_DEVICE_TYPE_CPU, 1, &device, NULL);
           if(err != CL_DEVICE_NOT_FOUND){
           break;
         }
       }
     }
   }
   CLHash_Utilities_HandleError(err, "CLHash_Utilities_CreateContext", "clGetDeviceIDs");

   if (DEBUG == 1) {
     char info[1024];
   
     printf("\n\n");
     printf("  Device:\n");
     clGetDeviceInfo(device, CL_DEVICE_NAME, sizeof(info), info, NULL);
     printf("    CL_DEVICE_NAME         : %s\n",info);

     clGetDeviceInfo(device, CL_DEVICE_VENDOR, sizeof(info), info, NULL);
     printf("    CL_DEVICE_VENDOR       : %s\n",info);
   }

   *context = clCreateContext(NULL, 1, &device, NULL, NULL, &err);
   if(err != CL_SUCCESS) CLHash_Utilities_PrintError_p(err, "CLHash_Utilities_CreateContext", "clCreateContext", file, line);

   *command_queue = clCreateCommandQueue(*context, device, CL_QUEUE_PROFILING_ENABLE, &err);
   if(err != CL_SUCCESS) CLHash_Utilities_PrintError_p(err, "CLHash_Utilities_CreateContext", "clCreateCommandQueue", file, line);

   free(platforms);
}

cl_program CLHash_Utilities_BuildProgramString_p(cl_context ctx, cl_device_id device, const char *programString, const char *file , int line){
   /* Create program from string */
   cl_int err;
   size_t program_size, nReportSize;
   program_size = strlen(programString);
   cl_program program = clCreateProgramWithSource(ctx, 1, (const char **)&programString, &program_size, &err);
   if(err != CL_SUCCESS) CLHash_Utilities_PrintError(err, "CLHash_Utilities_CreateDevice", "clCreateProgram");

   /* Build program */
   char *BuildReport;
   err = clBuildProgram(program, 0, NULL, NULL, NULL, NULL);
   if(err != CL_SUCCESS) {
      /* Find size of log and print to std output */
      clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG, 0, NULL, &nReportSize);

      if (err != CL_SUCCESS) {
        switch (err){
          case CL_INVALID_DEVICE:
            printf("Invalid device in clProgramBuildInfo\n");
            break;
          case CL_INVALID_VALUE:
            printf("Invalid value in clProgramBuildInfo\n");
            break;
          case CL_INVALID_PROGRAM:
            printf("Invalid program in clProgramBuildInfo\n");
            break;
        }
      }

      BuildReport = (char*) malloc(nReportSize + 1);
      BuildReport[nReportSize] = '\0';
      clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG, nReportSize + 1, BuildReport, NULL);
      printf("%s\n", BuildReport);
      free(BuildReport);
      exit(1);
   }

   return program;
}

/* Create program from a file and compile it */
cl_program CLHash_Utilities_BuildProgramFile_p(cl_context ctx, cl_device_id device, const char* fileName, const char *file , int line) {

   cl_program program;
   FILE *program_handle;
   char *program_buffer;
   size_t program_size;
   int err;

   /* Read program file and place content into buffer */
   program_handle = fopen(fileName, "r");
   if(program_handle == NULL) {
      perror("Couldn't find the program file");
      exit(1);
   }
   fseek(program_handle, 0, SEEK_END);
   program_size = ftell(program_handle);
   rewind(program_handle);
   program_buffer = (char*)malloc(program_size + 1);
   program_buffer[program_size] = '\0';
   fread(program_buffer, sizeof(char), program_size, program_handle);
   fclose(program_handle);
   program = CLHash_Utilities_BuildProgramString(ctx, device, program_buffer);
   free(program_buffer);
   return program;
}

void CLHash_Utilities_PrintError_p(cl_int err, const char *routine, const char *cl_routine, const char *file, int line){
  switch(err){
    case CL_DEVICE_NOT_FOUND:                //#define CL_DEVICE_NOT_FOUND                 -1
      printf("\nERROR: %s -- Device not found in %s at line %d in file %s\n", routine, cl_routine, line, file);
      break;
    case CL_DEVICE_NOT_AVAILABLE:            //#define CL_DEVICE_NOT_AVAILABLE             -2
      printf("\nERROR: %s -- Device not available in %s at line %d in file %s\n", routine, cl_routine, line, file);
      break;
    case CL_COMPILER_NOT_AVAILABLE:          //#define CL_COMPILER_NOT_AVAILABLE           -3
      printf("\nERROR: %s -- CL compiler not available failure in %s at line %d in file %s\n", routine, cl_routine, line, file);
      break;
    case CL_MEM_OBJECT_ALLOCATION_FAILURE:   //#define CL_MEM_OBJECT_ALLOCATION_FAILURE    -4
      printf("\nERROR: %s -- Mem object allocation failure in %s at line %d in file %s\n", routine, cl_routine, line, file);
      break;
    case CL_OUT_OF_RESOURCES:                //#define CL_OUT_OF_RESOURCES                 -5
      printf("\nERROR: %s -- Out of resources in %s at line %d in file %s\n", routine, cl_routine, line, file);
      break;
    case CL_OUT_OF_HOST_MEMORY:              //#define CL_OUT_OF_HOST_MEMORY               -6
      printf("\nERROR: %s -- Out of host memory in %s at line %d in file %s\n", routine, cl_routine, line, file);
      break;
    case CL_PROFILING_INFO_NOT_AVAILABLE:    //#define CL_PROFILING_INFO_NOT_AVAILABLE     -7
      printf("\nERROR: %s -- Profiling info not available in %s at line %d in file %s\n", routine, cl_routine, line, file);
      break;
    case CL_MEM_COPY_OVERLAP:                //#define CL_MEM_COPY_OVERLAP                 -8
      printf("\nERROR: %s -- Mem copy overlap in %s at line %d in file %s\n", routine, cl_routine, line, file);
      break;
    case CL_IMAGE_FORMAT_MISMATCH:           //#define CL_IMAGE_FORMAT_MISMATCH            -9
      printf("\nERROR: %s -- Image format mismatch in %s at line %d in file %s\n", routine, cl_routine, line, file);
      break;
    case CL_IMAGE_FORMAT_NOT_SUPPORTED:      //#define CL_IMAGE_FORMAT_NOT_SUPPORTED      -10
      printf("\nERROR: %s -- Image format not supported in %s at line %d in file %s\n", routine, cl_routine, line, file);
      break;
    case CL_BUILD_PROGRAM_FAILURE:           //#define CL_BUILD_PROGRAM_FAILURE           -11
      printf("\nERROR: %s -- Build program failure in %s at line %d in file %s\n", routine, cl_routine, line, file);
      break;
    case CL_MAP_FAILURE:                     //#define CL_MAP_FAILURE                     -12
      printf("\nERROR: %s -- Map failure in %s at line %d in file %s\n", routine, cl_routine, line, file);
      break;
    case CL_INVALID_VALUE:                   //#define CL_INVALID_VALUE                   -30
      printf("\nERROR: %s -- Invalid value in %s at line %d in file %s\n", routine, cl_routine, line, file);
      break;
    case CL_INVALID_DEVICE_TYPE:             //#define CL_INVALID_DEVICE_TYPE             -31
      printf("\nERROR: %s -- Invalid device type in %s at line %d in file %s\n", routine, cl_routine, line, file);
      break;
    case CL_INVALID_PLATFORM:                //#define CL_INVALID_PLATFORM                -32
      printf("\nERROR: %s -- Invalid platform in %s at line %d in file %s\n", routine, cl_routine, line, file);
      break;
    case CL_INVALID_DEVICE:                  //#define CL_INVALID_DEVICE                  -33
      printf("\nERROR: %s -- Invalid device in %s at line %d in file %s\n", routine, cl_routine, line, file);
      break;
    case CL_INVALID_CONTEXT:                 //#define CL_INVALID_CONTEXT                 -34
      printf("\nERROR: %s -- Invalid context in %s at line %d in file %s\n", routine, cl_routine, line, file);
      break;
    case CL_INVALID_QUEUE_PROPERTIES:        //#define CL_INVALID_QUEUE_PROPERTIES        -35
      printf("\nERROR: %s -- Invalid queue properties in %s at line %d in file %s\n", routine, cl_routine, line, file);
      break;
    case CL_INVALID_COMMAND_QUEUE:           //#define CL_INVALID_COMMAND_QUEUE           -36
      printf("\nERROR: %s -- Invalid command queue in %s at line %d in file %s\n", routine, cl_routine, line, file);
      break;
    case CL_INVALID_HOST_PTR:                //#define CL_INVALID_HOST_PTR                -37
      printf("\nERROR: %s -- Invalid host pointer in %s at line %d in file %s\n", routine, cl_routine, line, file);
      break;
    case CL_INVALID_MEM_OBJECT:              //#define CL_INVALID_MEM_OBJECT              -38
      printf("\nERROR: %s -- Invalid memory object in %s at line %d in file %s\n", routine, cl_routine, line, file);
      break;
    case CL_INVALID_IMAGE_FORMAT_DESCRIPTOR: //#define CL_INVALID_IMAGE_FORMAT_DESCRIPTOR -39
      printf("\nERROR: %s -- Invalid image format descriptor in %s at line %d in file %s\n", routine, cl_routine, line, file);
      break;
    case CL_INVALID_IMAGE_SIZE:              //#define CL_INVALID_IMAGE_SIZE              -40
      printf("\nERROR: %s -- Invalid image size in %s at line %d in file %s\n", routine, cl_routine, line, file); 
      break;
    case CL_INVALID_SAMPLER:                 //#define CL_INVALID_SAMPLER                 -41
      printf("\nERROR: %s -- Invalid sampler in %s at line %d in file %s\n", routine, cl_routine, line, file);
      break;
    case CL_INVALID_BINARY:                  //#define CL_INVALID_BINARY                  -42
      printf("\nERROR: %s -- Invalid binary in %s at line %d in file %s\n", routine, cl_routine, line, file);  
      break;
    case CL_INVALID_BUILD_OPTIONS:           //#define CL_INVALID_BUILD_OPTIONS           -43
      printf("\nERROR: %s -- Invalid build options in %s at line %d in file %s\n", routine, cl_routine, line, file);
      break;
    case CL_INVALID_PROGRAM:                 //#define CL_INVALID_PROGRAM                 -44
      printf("\nERROR: %s -- Invalid program in %s at line %d in file %s\n", routine, cl_routine, line, file);
      break;
    case CL_INVALID_PROGRAM_EXECUTABLE:      //#define CL_INVALID_PROGRAM_EXECUTABLE      -45
      printf("\nERROR: %s -- Invalid program executable in %s at line %d in file %s\n", routine, cl_routine, line, file);
      break;
    case CL_INVALID_KERNEL_NAME:             //#define CL_INVALID_KERNEL_NAME             -46
      printf("\nERROR: %s -- Invalid kernel name in %s at line %d in file %s\n", routine, cl_routine, line, file);
      break;
    case CL_INVALID_KERNEL_DEFINITION:       //#define CL_INVALID_KERNEL_DEFINITION       -47
      printf("\nERROR: %s -- Invalid kernel definition in %s at line %d in file %s\n", routine, cl_routine, line, file);
      break;
    case CL_INVALID_KERNEL:                  //#define CL_INVALID_KERNEL                  -48
      printf("\nERROR: %s -- Invalid kernel in %s at line %d in file %s\n", routine, cl_routine, line, file);
      break;
    case CL_INVALID_ARG_INDEX:               //#define CL_INVALID_ARG_INDEX               -49
      printf("\nERROR: %s -- Invalid arg index in %s at line %d in file %s\n", routine, cl_routine, line, file);
      break;
    case CL_INVALID_ARG_VALUE:               //#define CL_INVALID_ARG_VALUE               -50
      printf("\nERROR: %s -- Invalid arg value in %s at line %d in file %s\n", routine, cl_routine, line, file);
      break;
    case CL_INVALID_ARG_SIZE:                //#define CL_INVALID_ARG_SIZE                -51
      printf("\nERROR: %s -- Invalid arg size in %s at line %d in file %s\n", routine, cl_routine, line, file);
      break;
    case CL_INVALID_KERNEL_ARGS:             //#define CL_INVALID_KERNEL_ARGS             -52
      printf("\nERROR: %s -- Invalid kernel args in %s at line %d in file %s\n", routine, cl_routine, line, file);
      break;
    case CL_INVALID_WORK_DIMENSION:          //#define CL_INVALID_WORK_DIMENSION          -53
      printf("\nERROR: %s -- Invalid work dimension in %s at line %d in file %s\n", routine, cl_routine, line, file);
      break;
    case CL_INVALID_WORK_GROUP_SIZE:         //#define CL_INVALID_WORK_GROUP_SIZE         -54
      printf("\nERROR: %s -- Invalid work group size in %s at line %d in file %s\n", routine, cl_routine, line, file);
      break;
    case CL_INVALID_WORK_ITEM_SIZE:          //#define CL_INVALID_WORK_ITEM_SIZE          -55
      printf("\nERROR: %s -- Invalid work item size in %s at line %d in file %s\n", routine, cl_routine, line, file);
      break;
    case CL_INVALID_GLOBAL_OFFSET:           //#define CL_INVALID_GLOBAL_OFFSET           -56
      printf("\nERROR: %s -- Invalid global offset in %s at line %d in file %s\n", routine, cl_routine, line, file);
      break;
    case CL_INVALID_EVENT_WAIT_LIST:         //#define CL_INVALID_EVENT_WAIT_LIST         -57
      printf("\nERROR: %s -- Invalid event wait list in %s at line %d in file %s\n", routine, cl_routine, line, file);
      break;
    case CL_INVALID_EVENT:                   //#define CL_INVALID_EVENT                   -58
      printf("\nERROR: %s -- Invalid event in %s at line %d in file %s\n", routine, cl_routine, line, file);
      break;
    case CL_INVALID_OPERATION:               //#define CL_INVALID_OPERATION               -59
      printf("\nERROR: %s -- Invalid operation in %s at line %d in file %s\n", routine, cl_routine, line, file);
      break;
    case CL_INVALID_GL_OBJECT:               //#define CL_INVALID_GL_OBJECT               -60
      printf("\nERROR: %s -- Invalid GL object in %s at line %d in file %s\n", routine, cl_routine, line, file);
      break;
    case CL_INVALID_BUFFER_SIZE:             //#define CL_INVALID_BUFFER_SIZE             -61
      printf("\nERROR: %s -- Invalid buffer size in %s at line %d in file %s\n", routine, cl_routine, line, file);
      break;
    case CL_INVALID_MIP_LEVEL:               //#define CL_INVALID_MIP_LEVEL               -62
      break;

    default:
      printf("\nERROR: %s -- %d in %s at line %d in file %s\n", routine, err, cl_routine, line, file);
      break;
  }
  void* callstack[128];
  int frames = backtrace(callstack, 128);
  if (frames > 2) {
#ifdef HAVE_ADDR2LINE
     char hex_address[21];
     char command_string[80];
#endif
     char** strs = backtrace_symbols(callstack, frames);
     fprintf(stderr,"\n  =============== Backtrace ===============\n");
     for (int i = 1; i < frames-1; ++i) {
       fprintf(stderr,"   %s    \t", strs[i]);
#ifdef HAVE_ADDR2LINE
       if (program_name != NULL) {
          sscanf(strs[i],"%*s [%[^]]s]",hex_address);
       //printf("DEBUG addr2line -e clamr -f -s -i -p %s\n",hex_address);
          //sprintf(command_string,"addr2line -e %s -f -s -i %s | sed -e \'1,1s\?\\n\?\?' \n",program_name,hex_address);
          sprintf(command_string,"addr2line -e %s -f -s -i %s",program_name,hex_address);
          //printf("%s",command_string);
          system(command_string);
       }
       // on mac, need to install binutils using macports "port install binutils"
#endif
       fprintf(stderr,"\n");
    }
    fprintf(stderr,"  =============== Backtrace ===============\n\n");
    free(strs);
  }
  exit(-1);
}

const char* CLHash_Utilities_HandleError_p(cl_int err, const char *routine, const char *cl_routine, const char *file, int line){
  if(err != CL_SUCCESS) CLHash_Utilities_PrintError_p(err, routine, cl_routine, file, line);
  return(NULL);
}