view example/bitonic_sort/main.cc @ 2038:a78f8360c7f9 draft

modify bitonic sort. use sorting network
author Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
date Sat, 07 Feb 2015 02:34:46 +0900
parents 0b3d1d2863c8
children bc010492ade4
line wrap: on
line source

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/time.h>
#include <string.h>
#include "TaskManager.h"
#include "GpuScheduler.h"
#include "SchedTask.h"
#include "Func.h"

extern void task_init();
#ifdef GPU
extern void gpu_task_init();
#endif

void TMend(TaskManager *);

static double st_time;
static double ed_time;

CPU_TYPE spe_cpu = SPE_ANY;

int length = 1024;
int* data;

bool flag = false;

static double
getTime()
{
    struct timeval tv;
    gettimeofday(&tv, NULL);
    return tv.tv_sec + (double)tv.tv_usec*1e-6;
}

static void
print()
{
    for (int i=0; i<length; i++) {
        printf("%d ", data[i]);
    }
    puts("");
}

static void
check_data()
{
    for (int i=0; i<length-1; i++) {
        if (data[i+1] < data[i]) {
            printf("Data are not sorted at %d. %d > %d \n",i , data[i], data[i+1]);
            return;
        }
    }
    puts("Data are sorted");
}
            

const char *usr_help_str = "Usage: ./bitonic_sort [option]\n \
options\n                                                    \
  -cpu     Number of SPE used (default 1)\n                  \
  -l, --length  Sorted number of data (default 1200)\n       \
  -h, --help    Print this message\n";

void
init(int argc, char**argv){
    for (int i = 1; argv[i]; ++i) {
        if (strcmp(argv[i], "-g") == 0) {
            spe_cpu = GPU_0;
        } else if (strcmp(argv[i], "-any") == 0) {
            spe_cpu = ANY_ANY;
        } else if (strcmp(argv[i], "--length") == 0 || strcmp(argv[i], "-l") == 0) {
            length = (int)atoi(argv[++i]);
        }
    }
}

void run_start(TaskManager* manager) {
    int dummy = 0;
    int exp = 0;
    for (int i=0;; i++) {
        if (length <= (1<<i)) {
            exp = i;
            dummy = (1<<i) - length;
            length = 1<<i;
            break;
        }
    }

    data = (int*)malloc(length*sizeof(int*));
    for (int i=0; i<length; i++) {
        if (i<dummy) {
            data[i] = 0;
        } else {
            data[i] = manager->get_random()%1000000;
        }
    }

    //print();

    HTask* wait;
    HTask* swap;

    for (int i=2; i <= length; i=2*i) {
        bool first = true;
        for (int j=i>>1; 0 < j; j=j>>1) {
            swap = manager->create_task(SWAP);
            swap->set_inData(0, data, length*sizeof(int*));
            swap->set_outData(0, data, length*sizeof(int*));
            swap->set_param(0, (long)j);
            swap->set_param(1, (bool)first);
            swap->set_cpu(spe_cpu);
            swap->flip();
            if (flag)
                swap->wait_for(wait);
            swap->iterate(length/2);
            first = false;
            wait = swap;
        }
        flag = true;
    }
}
    

int TMmain(TaskManager *manager, int argc, char** argv) {
    task_init();
#ifdef GPU
    gpu_task_init();
#endif
    init(argc, argv);
    run_start(manager);
    st_time = getTime();
    manager->set_TMend(TMend);
    return 0;
}

void
TMend(TaskManager *manager)
{
    ed_time = getTime();
    printf("%0.6f\n",ed_time-st_time);
    //print();
    check_data();
}