Parallella Fan!
Home記事一覧BBS

公式サンプル「HelloWorld」を読む

概要

Epiphany SDKの公式サンプル「HelloWorld」に日本語で解説を付けました。

このソースコードを読めばEpiphanyプログラムの基本的な書き方が理解できます。

ホスト側プログラム本体:hello_world.c

/*
  hello_world.c

  Copyright (C) 2012 Adapteva, Inc.
  Contributed by Yaniv Sapir <yaniv@adapteva.com>

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program, see the file COPYING.  If not, see
  <http://www.gnu.org/licenses/>.
*/


// これはHello Worldサンプルのホスト側プログラムです。
// このプログラムはEpiphanyシステムを初期化し、ランダムにeCoreを
// 選択してEpiphanyプログラムをそのコアにロード、実行します。
// その後eCoreの出力したメッセージを共有外部メモリー・バッファから
// 読み込みます。


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

// Epiphanyホスト・ライブラリーをインクルード
#include <e-hal.h>

#define _BufSize   (128)

// 共有メモリの先頭 0x01000000 バイトはプログラム領域
// そこから 0x01000000 バイトがヒープ領域なので、
// バッファは 0x01000000 以降に確保します。
#define _BufOffset (0x01000000)
#define _SeqLen    (20)

int main(int argc, char *argv[])
{
  unsigned row, col, coreid, i;
  e_platform_t platform;
  e_epiphany_t dev;
  e_mem_t emem;
  char emsg[_BufSize];

  srand(1);

  // HDF(Hardware Description File)ファイルを
  // 読み込んでeHALシステムを初期化します。
  // int e_init(char *HDF);
  // (NULLを与えるとデフォルトのHDFファイルで初期化します。)

  e_init(NULL);

  // Epiphanyプラットフォームのフル・リセット
  // int e_reset_system();

  e_reset_system();

  // Epiphanyプラットフォーム情報を取得
  // int e_get_platform_info(e_platform_t *プラットフォーム);

  e_get_platform_info(&platform);

  // eCoreからホストへのメッセージの受け渡しのために
  // 共有外部メモリーにバッファを確保します。
  // int e_alloc(e_mem_t *共有バッファ, off_t ベースオフセット,
  //    size_t バッファサイズ);

  e_alloc(&emem, _BufOffset, _BufSize);

  for (i=0; i<_SeqLen; i++)
  {
    // ランダムにコアを選択
    row = rand() % platform.rows;
    col = rand() % platform.cols;
    coreid = (row + platform.row) * 64 + col + platform.col;
    fprintf(stderr, "%3d: Message from eCore 0x%03x (%2d,%2d): ",
      i, coreid, row, col);

    // コア単体のワークグループをOpenし、
    // すでに走っているプロセスがあればリセットします。
    // これ以降はそのワークグループ内におけるコア座標が
    // 使用されます。

    // eCoreワークグループの定義
    // int e_open(e_epiphany_t *Epiphany, unsigned ワークグループ起点Y座標,
    //  unsigned ワークグループ起点X座標, ワークグループサイズY, ワークグループサイズX);

    e_open(&dev, row, col, 1, 1);

    // ワークグループのソフトリセット
    // int e_reset_group(e_epiphany_t *Epiphany);

    e_reset_group(&dev);

    // Epiphanyプログラムを選択したコアにロードし、実行します。
    // int e_load(char *SRECファイル名, &Epiphany,
    //  unsigned ワークグループ内コア座標Y,
    //  unsigned ワークグループ内コア座標X, e_bool_t ロード後実行フラグ);

    e_load("e_hello_world.srec", &dev, 0, 0, E_TRUE);

    // Epiphanyプログラムの終了を待ちます。
    usleep(10000);

    // 共有バッファからメッセージを読み込みます。
    // ssize_t e_read(void *共有バッファ, unsigned ワークグループ内コア座標Y,
    //    unsigned ワークグループ内コア座標X, off_t 読み込み開始オフセット,
    //    void *読み込み先バッファ, size_t 読み込みバイト数);

    e_read(&emem, 0, 0, 0x0, emsg, _BufSize);

    // メッセージを表示
    fprintf(stderr, "\"%s\"\n", emsg);

    // ワークグループをClose
    // int e_close(e_epiphany_t *Epiphany);

    e_close(&dev);
  }

  // バッファを解放
  // int e_free(e_mem_t *共有バッファ);

  e_free(&emem);

  // Epiphanyプラットフォームへの接続を完了

  e_finalize();

  return 0;
}

Epiphany側プログラム本体:e_hello_world.c

/*
  e_hello_world.c

  Copyright (C) 2012 Adapteva, Inc.
  Contributed by Yaniv Sapir <yaniv@adapteva.com>

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program, see the file COPYING.  If not, see
  <http://www.gnu.org/licenses/>.
*/


// これはHello WorldサンプルのEpiphany側プログラムです。
// このプログラムはホストからeCoreのうちのどれかにロードされます。
// 起動後、コアIDを取得してメッセージを共有バッファに書き込みます。


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// Epiphanyハードウェア・ユーティリティ・ライブラリーをインクルード
#include "e_lib.h"

// リンカー・スクリプト・ファイルで設定されている共有メモリ領域に
// 配列を配置するように設定
char outbuf[128] SECTION("shared_dram");

int main(void) {
  e_coreid_t coreid;

  // 自分のコアID(eCoreの一意の識別子)を取得します。
  coreid = e_get_coreid();

  // printf等のライブラリ関数はローカルメモリに入りきらないので
  // リンカー・スクリプト(fast.ldf)でこれらの実体を
  // 外部メモリー(DRAM)に配置するよう設定しています。

  // メッセージを共有バッファに書き込みます。
  sprintf(outbuf, "Hello World from core 0x%03x!", coreid);

  return EXIT_SUCCESS;
}

ビルド・スクリプト:build.sh

#!/bin/bash

set -e

ESDK=${EPIPHANY_HOME}
ELIBS=${ESDK}/tools/host/lib
EINCS=${ESDK}/tools/host/include
# リンカー・スクリプト「fast.ldf」では、printf等の一部の
# ライブラリは外部のDRAM上に配置され、ユーザーの
# Epiphanyプログラム本体はローカルメモリーに配置されます。
ELDF=${ESDK}/bsps/current/fast.ldf

# ホスト側プログラムのビルド
gcc src/hello_world.c -o Debug/hello_world.elf -I ${EINCS} -L ${ELIBS} -le-hal

# Epiphany側プログラムのビルド
e-gcc -T ${ELDF} src/e_hello_world.c -o Debug/e_hello_world.elf -le-lib

# Epiphany側プログラムのバイナリをSRECファイル形式に変換します。
# このファイルがホスト側プログラムからEpiphanyに転送されます。
e-objcopy --srec-forceS3 --output-target srec Debug/e_hello_world.elf Debug/e_hello_world.srec

起動スクリプト:run.sh

#!/bin/bash

set -e

ESDK=${EPIPHANY_HOME}
ELIBS=${ESDK}/tools/host/lib:${LD_LIBRARY_PATH}
EHDF=${EPIPHANY_HDF}

cd Debug

# 現在のところ、eHALライブラリを使ったプログラムの実行には
# 管理者権限が必要です。(まだユーザー・レベル・ドライバになっていないため)
# そのためsudoで実行されます。
sudo -E LD_LIBRARY_PATH=${ELIBS} EPIPHANY_HDF=${EHDF} ./hello_world.elf

ダウンロード、ビルド、実行

Parallellaで端末を開きます。(lxterminal等)

Epiphany SDKリポジトリからファイルをダウンロードします。

wget -O epiphany-examples-master.zip https://github.com/adapteva/epiphany-examples/archive/master.zip

解凍します。

unzip epiphany-examples-master.zip

hello-world ディレクトリに移動。

cd epiphany-examples-master/apps/hello-world

ビルドします。

./build.sh

実行します。

./run.sh

端末にHello Worldと表示されます。これはEpiphanyプロセッサが書き込んだメッセージをARMホストが読み出して表示しています。

Hello World from core 0x...
...
...
...

このディレクトリには、hello-worldの他に、行列積のデモ「matmul-demo」や、2次元フーリエ変換のデモ「fft2d」等が収められています。ぜひこれらのプログラムも見てみてください。

上記の情報は米国Adapteva社が公開している情報を基にしたものです。出典元の著作物の権利は、米国Adapteva社など、その原著作権者に帰属します。