Vengineerの戯言

人生は短いけど、長いです。人生を楽しみましょう!

Vortex をビルドしてみた (その2)

はじめに

Vortex をビルドしてみた (その2)

./ci/blackbox.sh --driver=rtlsim --clusters=2 --cores=2 --warps=2 --threads=4 --app=basic

の --app=basic の中身をみてみます。

basic

tests/regression/basic の下の kernel.bin が RISC-V の 32ビットのelfファイルのようです。

cd tests/regression/basic
ls
Makefile  basic  common.h  kernel.bin  kernel.c  kernel.dump  kernel.elf  main.cpp  ramulator.ddr4.log
file kernel.*
kernel.bin:  data
kernel.c:    C source, ASCII text
kernel.dump: ASCII text
kernel.elf:  ELF 32-bit LSB executable, UCB RISC-V, version 1 (SYSV), statically linked, not stripped

この kernel.bin を

  • rtlsim
  • simx
  • vlsim

の3つのターゲットで実行します。

kernel.c

kernel.c は、アドレス KERNEL_ARG_DEV_MEM_ADDR に書き込まれた引数を使って、src_addr から dst_addr へcount * 4バイト(uint32_t) 分、コピーしています。これが vortex 内で実行われるんですね。

cat kernel.c
#include <stdint.h>
#include <vx_intrinsics.h>
#include "common.h"

void main() {
        kernel_arg_t* arg = (kernel_arg_t*)KERNEL_ARG_DEV_MEM_ADDR;
        uint32_t count   = arg->count;
        int32_t* src_ptr = (int32_t*)arg->src_addr;
        int32_t* dst_ptr = (int32_t*)arg->dst_addr;

        uint32_t offset  = vx_core_id() * count;

        for (uint32_t i = 0; i < count; ++i) {
                dst_ptr[offset + i] = src_ptr[offset + i];
        }
}

demo

tests/regression/demo の下の kernel.bin も basic と同様に RISC-V の 32ビットのelfファイルのようです。

cd tests/regression/demo
ls
Makefile  common.h  demo  kernel.bin  kernel.c  kernel.dump  kernel.elf  main.cpp
file kernel.*
kernel.bin:  data
kernel.c:    C source, ASCII text
kernel.dump: ASCII text
kernel.elf:  ELF 32-bit LSB executable, UCB RISC-V, version 1 (SYSV), statically linked, not stripped

kernel.c

こちらの kernel.c は、basic の kernel.c と非常に似ています。kernel_body 関数が basic の kernel.c の main 関数の中とほぼ同じです。

main 関数では、vx_spawn_tasks 関数を使って、kernel_body 関数を 引数 (arg) で呼び出しています。この arg は basic の main 関数内の arg と同じです。

cat kernel.c
#include <stdint.h>
#include <vx_intrinsics.h>
#include <vx_spawn.h>
#include "common.h"

void kernel_body(int task_id, kernel_arg_t* arg) {
        uint32_t count    = arg->task_size;
        int32_t* src0_ptr = (int32_t*)arg->src0_addr;
        int32_t* src1_ptr = (int32_t*)arg->src1_addr;
        int32_t* dst_ptr  = (int32_t*)arg->dst_addr;

        uint32_t offset = task_id * count;

        for (uint32_t i = 0; i < count; ++i) {
                dst_ptr[offset+i] = src0_ptr[offset+i] + src1_ptr[offset+i];
        }
}

void main() {
        kernel_arg_t* arg = (kernel_arg_t*)KERNEL_ARG_DEV_MEM_ADDR;
        vx_spawn_tasks(arg->num_tasks, (vx_spawn_tasks_cb)kernel_body, arg);

vx_spawn_task 関数は、runtime/vx_apawn.c の中で定義されています。

おわりに

--app=basic と --app=demo の中をみてみました