view example/HelloWorld/main.cc @ 2044:66aa91f6f4df draft

merge
author Shin,ichi Uehara
date Wed, 25 Mar 2015 19:13:56 +0900
parents 131d90cc3f85
children
line wrap: on
line source

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "TaskManager.h"
#include "Func.h"

extern void task_init(void);

static int count = 1;
static int spe_num = 1;

extern TaskManager *manager;
int use_task_creater = 0;

const char *usr_help_str = "Usage: ./hello [-cpu spe_num] [-count N]\n\
  -cpu    Number of SPE (default 1) \n\
  -count  Number of task is print \"Hello, World!!\"";

int
init(int argc, char **argv)
{
    for (int i = 1; argv[i]; ++i) {
        if (strcmp(argv[i], "-count") == 0) {
            count = atoi(argv[++i]);
        } else if (strcmp(argv[i], "-cpu") == 0) {
            spe_num = atoi(argv[i+1]);
        } else if (strcmp(argv[i], "-t") == 0) {
            use_task_creater = 1;
        }
    }
    return 0;
}


static void
simple_task_creater(int in_total_size, int out_total_size, 
                        int command, int in_data_size, int out_data_size, 
                        void *in_data, void *out_data, TaskManager *manager,
                        HTask *wait_i, HTask *wait_me)
{
    int in_task_size = 0;
    int out_task_size = 0;

    if (in_total_size != 0)
    {
        in_task_size = in_total_size / in_data_size;
        if (in_total_size != in_task_size * in_data_size) {
          printf("mismatch of in_total_size and in_data_size\n");
        }
    }

    if (out_total_size != 0) {
        out_task_size = out_total_size / out_data_size;
        if (out_total_size != out_task_size * out_data_size) {
            printf("mismatch of out_total_size and out_data_size\n");
        }
    }
  /*in, out の大きい方に合わせるのがいいかな? Taskの数は1Task分に使うデータの大きいほうを取るような仕様がいいかな*/
    int task_num = (in_task_size > out_task_size) ? in_task_size : out_task_size;

    if (task_num == 0) task_num = 1;

    /*spe分あればいいのかな?*/

    int array_num = spe_num;
    if (task_num < array_num) {
        array_num = task_num;
    }


    int array_length = task_num / array_num;
    int rest = task_num % array_num;

    HTaskPtr *task_array = (HTask**)manager->allocate(sizeof(HTask*)*array_num);
    TaskPtr *t_exec = (Task**)manager->allocate(sizeof(Task*)*array_length*array_num);

    int index = 0;
    for (int k = 0; k < array_num; k++) {
        task_array[k] = manager->create_task_array(command,array_length,0,1,1);
        t_exec[k] = 0;
        if (wait_me != 0) {
            wait_me->wait_for(task_array[k]);
        }
        if (wait_i != 0) {
            task_array[k]->wait_for(wait_i);
        }
    }

    for (int j = 0; j < array_length; j++) {
        for (int k = 0; k < array_num; k++) {
            t_exec[k] = task_array[k]->next_task_array(command,t_exec[k]);
            t_exec[k]->set_inData(0,(char*)in_data + index*in_data_size, in_data_size);
            t_exec[k]->set_outData(0,(char*)out_data + index*out_data_size, out_data_size);

            index++;
        }
    }

    for (int k = 0; k < array_num; k++) {
        task_array[k]->spawn_task_array(t_exec[k]->next());
        task_array[k]->set_cpu(SPE_ANY);
        task_array[k]->spawn();
    }

    for (int k = 0; k < rest; k++) {
        HTaskPtr t_exec = manager->create_task(command);

        t_exec->set_inData(0,(char*)in_data + index*in_data_size, in_data_size);
        t_exec->set_outData(0,(char*)out_data + index*out_data_size, out_data_size);

        index++;

        if (wait_me != 0) wait_me->wait_for(t_exec);
        if (wait_i != 0) t_exec->wait_for(wait_i);

        t_exec->set_cpu(SPE_ANY);
        t_exec->spawn();
    }
}

void
hello_init(TaskManager *manager)
{
    for (int i = 0; i < count; i++) {
        /**
         * Create Task
         * create_task(Task ID);
         */
        if (use_task_creater) {
            simple_task_creater(0,0,HELLO_TASK,0,0,0,0,manager,0,0);
        } else {
            HTask *hello = manager->create_task(HELLO_TASK);
            /**
             * Select CPU
             *   SPE_0, SPE_1, SPE_2, SPE_3, SPE_4, SPE_5, SPE_ANY
             *   if you do not call this, execute PPE.
             */
            hello->set_cpu(SPE_ANY);

            /**
             * Set 32bits parameter
             *   add_param(32bit parameter);
             */
            hello->set_param(0,(long)i);

            hello->spawn();
        }
    }
}

int
TMmain(TaskManager *manager, int argc, char *argv[])
{
    if (init(argc, argv) < 0) {
        return -1;
    }

    // Task Register
    // ppe/task_init.cc
    task_init();
    hello_init(manager);
    return 0;
}