libmcl-sys 0.1.2-rc1

This system crate provides Rust language bindings to the Minos Compute Library (MCL)
Documentation
#include <stdio.h>
#include <time.h>
#include <config.h>
#include <inttypes.h>

#include "utils.h"

//#define VERBOSE

uint64_t workers = DFT_WORKERS;
size_t   size    = DFT_SIZE;
uint64_t type    = DFT_TYPE;
uint64_t synct   = DFT_SYNC;
uint64_t rep     = DFT_REP;
uint64_t verify  = DFT_VERIFY;
uint64_t did     = DFT_DID;
uint64_t flags   = 0x0;
struct timespec start, end;

const struct option global_lopts[] = {
#ifdef __TEST_MCL
        {"workers",     0, NULL, 'w'},
	{"sync",        0, NULL, 'x'},
#endif
#ifdef __TEST_OCL
        {"device",      0, NULL, 'd'},
#endif
	{"rep",         0, NULL, 'r'},
        {"size",        0, NULL, 's'},
	{"type",        0, NULL, 't'},
	{"verify",      0, NULL, 'v'},
        {"help",        0, NULL, 'h'},
        {NULL,          0, NULL, 0}
};

void print_global_help(char* prog)
{
        printf("Usage: %s <options>\n", prog);
#ifdef __TEST_MCL
        printf("\t -w, --workers   <n> Number of workers (default = %lu)\n", DFT_WORKERS);
	printf("\t -t, --type      <n> Type of resource  (default = %lu, 0=CPU, 1=GPU, 2=ANY)\n",
	    	DFT_TYPE);
	printf("\t -x, --sync      Synchronous test      (default = %lu, 0=ASYNC, 1=SYNC)\n",
	    	DFT_SYNC);
#endif
#ifdef __TEST_OCL
	printf("\t -t, --type      <n> Type of resource  (default = %lu, 0=CPU, 1=GPU)\n",
	    	DFT_TYPE);
	printf("\t -d, --device    <n> Device ID  (default = %lu)\n", DFT_DID);
#endif	
        printf("\t -s, --size      <n> Size of matrix    (default = %lu)\n", DFT_SIZE);
	printf("\t -r, --rep       <n> Repetitions       (default = %lu)\n", DFT_REP);
	printf("\t -v, --verify    Verify execution      (default = %lu)\n", DFT_VERIFY);
	printf("\t -h, --help      Show help\n");

        exit(EXIT_FAILURE);
}

void parse_global_opts(int argc, char** argv)
{
        int opt;
        char* end;

        do{
#ifdef __TEST_MCL
                opt = getopt_long(argc, argv, "w:s:t:r:xvh", global_lopts, NULL);
#endif
#ifdef __TEST_OCL
                opt = getopt_long(argc, argv, "s:t:r:d:vh", global_lopts, NULL);
#endif
				
                switch(opt){
                case 'h':
                        print_global_help(argv[0]);
                        exit(EXIT_FAILURE);
#ifdef __TEST_MCL
                case 'w':
                        workers = strtol(optarg, &end, 10);
                        if(*end){
                                printf("Error converting %s as workers.\n",optarg);
                                exit(EXIT_FAILURE);
                        }
                        break;
		case 'x':
			synct = 1UL;
                        break;
#endif
#ifdef __TEST_OCL
                case 'd':
                        did = strtol(optarg, &end, 10);
                        if(*end){
                                printf("Error converting %s as device ID.\n",optarg);
                                exit(EXIT_FAILURE);
                        }
                        break;
#endif
                case 's':
                        size = strtol(optarg, &end, 10);
                        if(*end){
                                printf("Error converting %s as vector size.\n",optarg);
                                exit(EXIT_FAILURE);
                        }
                        break;
		case 'r':
                        rep = strtol(optarg, &end, 10);
                        if(*end){
                                printf("Error converting %s as number of repetitions.\n",optarg);
                                exit(EXIT_FAILURE);
                        }
                        break;
                case 't':
                        type = strtol(optarg, &end, 10);
                        if(*end){
                                printf("Error converting %s as PE type.\n",optarg);
                                exit(EXIT_FAILURE);
                        }
                        break;
		case 'v':
			verify = 1UL;
			synct  = 1UL;
                        break;
                case -1:
                        break;
                default:
                        printf("Option %c not regognized!. Aborting.\n",opt);
                        print_global_help(argv[0]);
                        exit(EXIT_FAILURE);
                }
        }while(opt != -1);

        printf("Parsed options: \n");
#ifdef __TEST_MCL
        printf("\t Number of workers     = %"PRIu64"\n", workers);
	printf("\t Type of test          = %s\n", synct?"Sync":"Async");
#endif
#ifdef __TEST_OCL
        printf("\t Device ID             = %"PRIu64"\n", did);
#endif
        printf("\t Matrix size           = %ld\n"        , size);
	printf("\t Number of repetitions = %"PRIu64"\n"  , rep);
	printf("\t Type of PEs           = %"PRIu64"\n"  , type);
	printf("\t Verify test           = %s\n"         , synct?"Yes":"No");
}

void mcl_banner(char* name)
{
	time_t t;

	printf("\n\n");
	printf("===========================================\n");
	printf("    %s\n", PACKAGE_NAME);
	printf("    %s\n",name);
	printf("===========================================\n");
	printf("Version:    %s\n", PACKAGE_VERSION);
	t = time(NULL);
	printf("Start time: %s",ctime(&t));
	printf("-------------------------------------------\n");
	clock_gettime(CLOCK_MONOTONIC, &start);
}

void mcl_verify(int res)
{
	time_t t;

	clock_gettime(CLOCK_MONOTONIC, &end);
	t = time(NULL);
	printf("-------------------------------------------\n");
	printf("End time:       %s", ctime(&t));
	printf("Result:         %s\n",res? TEST_FAILED: TEST_SUCCESS);
	printf("Execution time: %f seconds\n", ((float)tdiff(end,start))/BILLION);
	printf("===========================================\n");
}

int mcl_load(char* file, char** src)
{
	int fd;
	size_t n;
	
	fd = open(file, O_RDONLY);
	if(fd == -1){
		printf("\n Error opening OpenCL code. Aborting.\n");
		goto err;
	}
	n = lseek(fd, 0, SEEK_END);

	*src = (char*) malloc(n+1);
	if(!src){
		printf("Error allocating memory to store OpenCL code. Aborting.\n");
		goto err_file;
	}

	lseek(fd, 0, SEEK_SET);
	if(read(fd, (void*) *src, n) != n){
		printf("Error loading OpenCL code. Aborting.\n");
		goto err_src;
	}

	(*src)[n] = '\0';
#ifdef VERBOSE
	printf("Loaded source, size %lu\n ", n);
#endif
	return 0;

 err_src:
	free(*src);
 err_file:
	close(fd);
 err:
	return -1;
}

int ocl_setup(cl_device_id** dev, cl_context* ctxt, cl_command_queue* q, unsigned long type, unsigned long id)
{
	cl_int          ret = 0;
	cl_platform_id* platforms = NULL;
	cl_uint         nplatforms, ndevices, i;
	
	ret = clGetPlatformIDs(0, NULL, &nplatforms);
	if(ret != CL_SUCCESS){
		printf("Error querying CL platforms! Aborting. (%d)\n", ret);
		goto err;
	}
#ifdef VERBOSE
	printf("Found %d platforms.\n", nplatforms);
#endif
	platforms = (cl_platform_id*) malloc(sizeof(cl_platform_id) * nplatforms);
	if(!platforms){
		printf("Error allocating mameory for CL platforms. Aborting.");
		goto err;
	}
	
	ret = clGetPlatformIDs(nplatforms, platforms, NULL);
	if(ret != CL_SUCCESS){
	    printf("Error querying CL platforms! Aborting. (%d)\n", ret);
	    goto err_plt;
        }

	ret = CL_DEVICE_NOT_FOUND;
	for(i=0; i<nplatforms; i++){
	     ret = clGetDeviceIDs(platforms[i], type, 0, NULL, &ndevices);
	     if(ret == CL_SUCCESS && ndevices){
		     *dev = (cl_device_id*) malloc(sizeof(cl_device_id) *  ndevices);
		     if(*dev == NULL){
			     printf("Error allocating mameory for CL devices. Aborting.");
			     goto err_plt;
		     }
		     ret = clGetDeviceIDs(platforms[i], type, ndevices, *dev, NULL);
		     break;
	     }	     
        }

	if(ret != CL_SUCCESS){
		printf("Error querying CL devices for type 0x%lx. (%d)\n", type, ret);
		goto err_plt;
	}
	
#ifdef VERBOSE
	printf("Found %d compatible devices.\n", ndevices);
#endif
	
	*ctxt = clCreateContext( NULL, ndevices, *dev, NULL, NULL, &ret);
	if(ret != CL_SUCCESS){
		printf("Error creating context! Aborting. (%d)\n", ret);
		goto err_plt;
	}
	
#ifdef OPENCL2
    cl_command_queue_properties props[3] = {CL_QUEUE_PROPERTIES, 0, 0};
	*q = clCreateCommandQueueWithProperties(*ctxt, *(*dev + id), props, &ret);
#else
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
    *q = clCreateCommandQueue(*ctxt, *(*dev + id), NULL, &ret);
#pragma GCC diagnostic pop
#endif
    if(ret != CL_SUCCESS){
		printf("Error creating command queue! Aborting. (%d)\n", ret);
		goto err_plt;
	}

 err_plt:
	free(platforms);
 err:
	return ret;
}