1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

2つの関数が同じ入力なら同じ結果を返すことを保障するテストフレームワーク(2)

Last updated at Posted at 2025-07-16

前回までで、IntelからOpenPOWERやRISC-VにIntrinsic関数をポートする方法について議論してきた。
ポートには、以下のようなラッパー構造でIntelのIntrinsic関数を置換してやる。

extern __inline  __m128d  __attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_cmpeq_sd(__m128d  __A, __m128d  __B)
{
  __v2df __a, __b, __c;
  /* PowerISA VSX does not allow partial (for just lower double)
     results. So to insure we don't generate spurious exceptions
     (from the upper double values) we splat the lower double
     before we do the operation. */
  __a = vec_splats (__A[0]);
  __b = vec_splats (__B[0]);
  __c = (__v2df) vec_cmpeq(__a, __b);
  /* Then we merge the lower double result with the original upper
     double from __A.  */
  return (__m128d) _mm_setr_pd (__c[0], __A[1]);
}

ここで湧き上がってくる疑問がある、このポートしたラッパー構造は本当に正しいのだろうか。
そこで必要なのは、__A__Bにランダムに生成した値を入力してやり、それをIntelとOpenPOWER側に入れてやって、帰ってくる値が同じであることを確認することである。

そこで必要なのは、__A__Bと、帰ってきた値をセットにして、ファイルに保存することである。

ファイルに保存するフォーマットとしては、XMLかJSONが良いと思う。では、保存するファイルフォーマットを記述していこう。toukaはテストフレームワーク燈花の名前である。等価をかけている。

<touka>
<head><version>1.00</version></head>
<body>
<IO><input><__A>(__Aの値をテキストに変換したもの)</__A><__B>(__Bの値をテキストに変換したもの)</__B></input>
<output>(帰ってきた値をテキストに変換したもの)</output></IO>
<IO><input><__A>(__Aの値をテキストに変換したもの)</__A><__B>(__Bの値をテキストに変換したもの)</__B></input>
<output>(帰ってきた値をテキストに変換したもの)</output></IO>
(テストの回数繰り返す)
<body>
</touka>

同じものをJSONで書いてみる。

{"touka":{"head":{"version":1.00},
"body":
{"IO":{"input":{"__A":"FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA","__B":"FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA"},"output":{"return":"FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA"}}},
"IO":{"input":{"__A":"FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA","__B":"FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA"},"output":{"return":"FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA"}}}}

この<IO>タグのついた部分が、テストされた分入っている。
このJSONファイルをIntel側で生成して、ファイル転送によりOpenPOWERまたは、RISC-Vに移動し、ポートされたソースコードが正しいことを確認する。
値をテキストに変えるフォーマットについて議論をする必要がある。

JSONの作成またはパースをJavaで行い、それをC言語で作ったSIMD部に送信する手があるが、インターフェースを考えないといけない。
Java Native Interfaceを使う手がある。それについて考えていこうと思う。

Java部で、一回のIntrinsic関数実行分のデータを小分けにしてStringにしてSIMD部に送って、SIMD部でC言語の型にすることができる。

なので、C言語で、「C言語の型↔String」の変換モジュールを制作する必要がある。
Stringは__m128d単体のものでよく、伝達したり小分けにするのはJava部の役割である。
その場合、__m128dはIntel x86-64用のSIMD型であるため、それをOpenPOWERまたはRISC-Vにポートしたものにも対応する必要がある。
例えば、__m128d単体をシリアライズする方法にはunionを使った以下のようなものがある。調査には生成AIを使った。このコードがRISC-VおよびOpenPOWERでも正常に動くか確認しないといけない。
次回から、__m128dのシリアライズとデシリアライズについて議論していこうかと思う。

typedef union {
    __m128d v;
    double d[2];
} m128d_union;

void serialize_m128d(__m128d v, char *buf, size_t bufsize) {
    m128d_union u;
    u.v = v;
    snprintf(buf, bufsize, "[%f, %f]", u.d[0], u.d[1]);
}
1
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?