• 検索結果がありません。

スライド 1

N/A
N/A
Protected

Academic year: 2021

シェア "スライド 1"

Copied!
41
0
0

読み込み中.... (全文を見る)

全文

(1)

2013年7月

加藤 努

株式会社 ソフテック

PGI Accelerator Compiler

GTC Japan 2013

新OpenACC 2.0の機能と

PGIアクセラレータコンパイラ

(2)

本日の話

OpenACC 1.0の復習

ディレクティブ操作で 出来ることを再確認

OpenACC

2.0の新機能

プログラミングの自由度の 向上へ

PGI Accelerator Compiler 2013

• PGI Accelerator Programming Model 準拠

• OpenACC 1.0 準拠

• OpenACC 2.0 の機能は、毎月のリビジョンで順次追加

• プラスPGI Extension(先取り機能)

OpenACCディレクティブで出来ることを

改めて知ろう!

(3)

PGI Accelerator / OpenACC Release Map

2007 2010 2013

NVIDIA CUDA release

2008 2009 2011 2012

PGI Accelerator Programming Model 公開 (OpenACCの原型モデル

PGI Accelerator Compiler リリース (PGI 2010)

OpenACC API 1.0 release

OpenACC 1.0準拠 PGI Compiler リリース(PGI 2012) OpenACC 2.0

順次取込 (PGI 2013)

OpenMP 4.0 with extensions for Accelerators

OpenACC API 2.0 final

PGI 提供開始

PGIは、2009年より提供開始

(4)

OpenACC Programming Model

CPU

Main

Memory

Device

Device

Memory

② データの移動管理

ホスト側

Accelerator側

オフロードモデル

重い計算部分の 処理をオフロード 「重い処理部分」をアクセラレータ側で処理するモデル

① 処理の並列化(分割指示)

並列処理による

スループット改善

(5)

OpenACCディレクティブの主な構成

CPU

Main

Memory

GPGPU

Device

Memory

ホスト

Accelerator

重い計算部分の 処理をオフロード

① Accelerate Compute 構文 (offload 領域指示)

② Data 構文 (データ移動指示)

③ Loop 構文 (Mapping for parallel/vector, Tuning)

(処理)

(6)

OpenACC 1.0 ディレクティブの復習

まだ、ハードルが高いあなたに!

① どこをオフロードの対象とするか?

コンパイラに対する指示、ユーザが行う最初のステップ

② データ・マネージメントの方法

データの移動指示 ・コンパイラが自動的に行う ・ユーザによる明示的な指示 ホスト上、デバイス上にコピー

③ 並列処理の分割方法の指示

Mapping (並列チューニング)のdirectives

後は、コンパイラに任せる

(7)

① 並列化(オフロード)領域の対象は?

A. 並列化可能な「ループ」、「ループの集合体」

for( i = 0; i < nrows; ++i ){ double val = 0.0;

int nstart = rowindex[i]; int nend = rowindex[i+1];

for( n = nstart; n < nend; ++n )

val += m[n] * v[colndx[n]];

r[i] = val;

}

for( i = 0; i < n; ++i )

a[i] = b[i] + c[i];

for (i = 0; i < n; i++){ for (j = 0; j < n; j++){ for (k = 0; k < n; k++){ C[i*n+j] = A[i*n+k] * B[k*n+j]; } } }

Non-tightly Nested Loops

tightly Nested Loops Single Loops

for( i = 0; i < n; ++i )

a[i] = b[i] + cdd[i];

for( i = 1; i < n-1; ++i )

c[i] = 0.5 * a[i-1] + a[i+1];

Ajacent(隣接) Loops

Q. どこをオフロードの対象とするのか?

(どこにdirectiveを入れるか)

(8)

プログラム・シーケンス上でのオフロード対象

for (cgit = 1; cgit <= cgitmax; cgit++) {

rho0 = rho; d = 0.0;rho = 0.0;

for (j = 1; j <= lastrow-firstrow+1; j++) {

sum = 0.0;

for (k = rowstr[j]; k < rowstr[j+1]; k++) {

sum = sum + a[k]*p[colidx[k]];

} w[j] = sum; q[j] = sum; } ……(snip)…… for (j = 1; j <= lastcol-firstcol+1; j++) { d = d + p[j]*q[j]; } alpha = rho0 / d; (ホスト上でスカラ演算) for (j = 1; j <= lastcol-firstcol+1; j++) {

double new_rj = r[j] - alpha*q[j]; z[j] = z[j] + alpha*p[j];

r[j] = new_rj;

rho = rho + new_rj*new_rj; }

……(snip)……

beta = rho / rho0; (ホスト上でスカラ演算) ……(snip)…… } 外側繰り返しループ 外側繰り返しループ Nested loop (並列化可能) Single loop (並列化可能) Single loop (並列化可能) OpenACC directive OpenACC directive OpenACC directive

(9)

並列化(オフロード)できないループ

do k = 1, d3 do jj = 0, d2 - fftblock, fftblock do j = 1, fftblock do i = 1, d1 y1(j,i) = x(i,j+jj,k) enddo enddo

call cfftz (is, logd1, d1, y1, y2) do j = 1, fftblock do i = 1, d1 xout(i,j+jj,k) = y1(j,i) enddo enddo enddo enddo Nested loop (並列化可能) ループ内に Procedure Callがあると 並列化出来ない Kループはオフロード化できない Nested loop (並列化可能) ループ内に Function call • OpenACC API 1.0 では並列化できない

• NVIDIA CUDA 5.0からGPUカーネルのリンカー機能が追加

されたことのより、

OpenACC 2.0で可能

となる

並列化を行うには、インライン展開 するしかなかった!

(10)

② OpenACCにおけるデータ移動の基本

「ホストとデバイス」間のデータ交換のタイミングポイントは?

!$acc end kernels

do k=1,n do j=1,n do i=1,n a(i,j.k)=b(i,j,k)*c(i,j,k) enddo enddo enddo !$acc kernels

Gang Gang Gang

!$acc parallel

!$acc end parallel

コンパイラのデフォルト動作

OpenACC 並列化構文(acc kernels や acc parallel) の始点と終点で その領域内で使われている配列、スカラ変数を解析し、「ホスト」と

「デバイス」間のデータコピーを行うコードを暗黙に自動生成

• ユーザが明示的にコピー配列名を指示(copy clause)することができる

• live スカラ変数は、デフォルトでcopyin/copyout されている (スカラ変数の移動管理は明示的に必要なし)

(11)

データ・マネージメントの基本的考え方

「ホスト」と「デバイス」間のデータの移動を最小化すること

デバイス上で可能な限りのデータ常駐化 ホスト側から一度、デバイスへコピー(copyin)された配列データは、デバイス 側の計算で役目が終わらない限り、ホスト側へデータ(copyout)を戻さない

プログラミング上の鉄則

Fortran !$acc data [clause …]

...

!$acc end data

C #pragma acc data [clause …] { ...}

Data 構文 directive の活用

ユーザが明示的にデータ移動を管理するための構文

(12)

デバイス内にデータを常駐化する

!$acc data copy (a(100))

A(100) A(100) Host側メモリ デバイス側メモリ Main routine (host側) A A A A A デバイス側 の処理

!$acc end data

copyin copyout resident time “present” と言う状態

call call call

!$acc data present(a(100))

「Data 構文」で挟まれたプログラム領域に適用できる

プログラムの流れ

(13)

データの同期 update directive(実行文)

!$acc data copy (a(100))

A(100) A(100)

Host側メモリ デバイス側メモリ

A

A A A

A

!$acc end data

copyin copyout

resident

“present” と言う状態

call call call

A

!$acc data present(a(100))

!$acc update host (a(10:20))

!$acc update device (a(10:20))

Device to host Host to device Main routine (host側) デバイス側 の処理 細かな操作が可能

(14)

実際のプログラムでdirectiveの適用

int main(int argc, char **argv) { read_input();

domain(); setcoeff();

#pragma acc data create(u,rsd,frct,flux,a,b,c,d)

copyin(ce) copyout(u) { setbv(); setiv(); erhs(); ssor();

} /* end acc data */ error();

Nested loop (並列化可能) データの移動管理のdirective

OpenACC data directive

OpenACC directive static void ssor(void) {

for (istep = 1; istep <= itmax; istep++) { /* perform SSOR iteration */

#pragma acc kernels present(rsd)

for (i = ist; i <= iend; i++) { for (j = jst; j <= jend; j++) { for (k = 1; k <= nz - 2; k++) { for (m = 0; m < 5; m++) { rsd[i][j][k][m] = dt * rsd[i][j][k][m]; } } } } (以下、略) Accelerator Data 領域管理下 function call 並列領域指定のdirective Mainルーチン+Subroutineタイプ

(15)

③ 並列処理の対象と方法を指示する構文

アクセラレータ上で

並列実行を行う領域を指定

するためのdirective

その領域内で使用する「データ」を転送するコードを生成(Implicit xfer)

 Parallel 構文

(1つのカーネル構成でコード生成)

C #pragma acc parallel {並列実行領域}

Fortran !$acc parallel {並列実行領域}

!$acc end parallel

 Kernels 構文

(tightly loopsを対象、複数のカーネルで構成)

C #pragma acc kernels {並列ループ領域}

Fortran !$acc kernels

{並列ループ領域} !$acc end kernels

(16)

並列処理分割の指示を行う Loop構文

Fortran !$acc loop [clause …]

C #pragma acc loop [clause …]

Clause() collapse (n) gang [ ( expression ) ] worker [ ( expression ) ] vector [ ( expression ) ] seq independent private( list )

reduction ( operator : list)

• 直下の「ループ」の並列の分割方法(gang, worker, vector)指示

• Acceleratorハードウェアの並列構造にマッピングを行うためのclause

• ループ内プライベートとなる変数の宣言

• リダクション処理の指定

(17)

OpenACC Parallelism 3階層

worker

Gang

PEs => Streaming Multiprocessors

Gang

Worker

Vector

PEs :プロセッサ要素の基本集合体

each PE :マルチスレッディング処理

Each thread of the PE : ベクトル命令処理

Multithreaded Worker thread thread あまり深刻に考えなくてよい = H/W とのマッピングが難しい Vector命令(長さ) PE

Multithreading => warps within SM

Vector_length => warp内スレッド数32

(PE内の Max. Threads per Thread Block)

(18)

並列処理分割の指示 loop構文

#pragma acc kernels

#pragma acc loop independent

for (i = 1; i < n+1; i++) {

#pragma acc loop independent

for (j = 1; j < n+1; j++) {

#pragma acc loop independent

for (k = 1; k < n+1; k++) { a1[i*sz*sz+j*sz+k] = ( a0[i*sz*sz+(j-1)*sz+k] + a0[i*sz*sz+(j+1)*sz+k] + …省略… a0[i*sz*sz+j*sz+(k-1)] + a0[i*sz*sz+j*sz+(k+1)] ) * fac; } } }

Accelerate Compute

構文

Loop

構文

161, Loop is parallelizable

Accelerator kernel generated

161, #pragma acc loop gang /* blockIdx.x */

165, #pragma acc loop vector(128) /* threadIdx.x */

(並列対象指示)

(並列分割指示)

(19)

並列分割の指示 loop構文

#pragma acc kernels

#pragma acc loop independent gang(32)

for (i = 1; i < n+1; i++) {

#pragma acc loop independent

for (j = 1; j < n+1; j++) {

#pragma acc loop independent vector(32)

for (k = 1; k < n+1; k++) { a1[i*sz*sz+j*sz+k] = ( a0[i*sz*sz+(j-1)*sz+k] + a0[i*sz*sz+(j+1)*sz+k] + …省略… a0[i*sz*sz+j*sz+(k-1)] + a0[i*sz*sz+j*sz+(k+1)] ) * fac; } } }

Accelerate Compute

構文

Loop

構文

161, Loop is parallelizable

Accelerator kernel generated

161, #pragma acc loop gang(32) /* blockIdx.x */ 165, #pragma acc loop vector(32) /* threadIdx.x */

(並列対象指示)

(並列分割指示)

(20)

OpenACC API 2.0

(21)

OpenACC API 2.0 New features

「手続きの呼び出し」 と 「分離コンパイル」

(効果) プログラム移行性向上、ライブラリとしてモジュール化可能

入れ子(Nested)並列

(効果) parallel/kernels構文を有するルーチン・モジュールを構成可能

デバイス特有なチューニング, 複数のデバイス使用

(効果) デバイス種に依存しない「性能互換性」の向上

グローバル・データへの対応

(効果) ルーチン間での「広域データ」の使用の単純化

データ・マネージメント自由度向上

(効果) unstructured data lifetimes(自由にデータ領域を構築)

新しい Data API ルーチン

(

より自由にデータ移動が可能

Loop 構文のparallelism 3階層の明確化と auto、tile節の追加

(効果) 並列性3階層の整理、ユーザ・チューニングの簡易化

非同期操作の向上

(22)

現在、手続きの呼び出しがあると?

Accelerator Compute領域の 中の call 文を含むループは、 並列化できない。

OpenACC 1.0では、関数、手続きをソースレベルで

インライン展開をするしかなかった。

OpenACC 2.0 では可能になる。

#pragma acc parallel loop num_gangs(200)…

for ( int i = 0; i < n; ++i ) { v[i] += rhs[i];

matvec( v, x, a, i, n );

// デバイスへの function call

(23)

OpenACC 2.0 Function Call support

#pragma acc routine worker

extern void matvec(float* v, float* x, … );

#pragma acc parallel loop num_gangs(200)…

for ( int i = 0; i < n; ++i ){ v[i] += rhs[i];

matvec( v, x, a, i, n );

// デバイスへの function call

} omp end parallel

① 「手続きのプロトタイプ」に指示 worker レベルの並列処理を 指示する例 Function 内でworkerレベルの並列処理を指示する場合は、その上位の parallel/kernels 構文内の上位loopの並列レベルは、gangレベルである 必要がある。同じ workerレベルは駄目。

(24)

OpenACC 2.0 “routine” directive

#pragma acc routine worker

extern void matvec(float* v, float* x, … );

#pragma acc parallel loop num_gangs(200)…

for ( int i = 0; i < n; ++i ){ v[i] += rhs[i];

matvec( v, x, a, i, n );

// デバイスへの function call

} omp end parallel

#pragma acc routine worker

void matvec( float* v, float* x, float* a, int i, int n ) { float xx = 0;

#pragma acc loop reduction(+:xx)

for ( int j = 0; j < n; ++j ) xx += a[i*n+j]*v[j]; x[i] = xx; } ① 「手続きのプロトタイプ」に指示 worker レベルの並列処理を 指示する例 ② 「手続き」への”routine”指示

“orphaned” loop directive 分離コンパイルも可能

(25)

OpenACC 2.0 Nested Parallelism (1)

#pragma acc routine

extern void matvec(float* v,float* x, … );

#pragma acc parallel loop …

for ( int i = 0; i < n; ++i )

matvec( v, x, i, n );end parallel

#pragma acc routine void matvec( … ) {

#pragma acc parallel loop

for ( int i = 0; i < n; ++i ) { … }

parallel or kernels 領域内の ループ内から call function function側でも、 parallel or kernels loop を構成できる 実際は、 “i “ 毎にデバイスの中の シングル・スレッドで次々に開始する

matvec内で、指定された parallelism を launch する

(26)

OpenACC 2.0 Nested Parallelism (2)

#pragma acc routine

extern void matvec(float* v,float* x, … );

#pragma acc parallel loop num_gangs(1) … {

matvec( v0, x0, i, n );e

matvec( v1, x1, i, n );end

matvec( v2, x2, i, n );e

}

#pragma acc routine void matvec( … ) {

#pragma acc parallel loop

for ( int i = 0; i < n; ++i ) { … }

一つのデバイス・スレッドで 次々に matvec を起動する

(27)

異なるデバイスへの指示 device_type

#pragma acc parallel loop num_gangs(200)…

for ( int i = 0; i < n; ++i ) { v[i] += rhs[i];

matvec( v, x, a, i, n ); } omp end parallel

#pragma acc parallel loop \

device_type(nvidia) num_gangs(200) \ device_type(radeon) num_gangs(400) …

for ( int i = 0; i < n; ++i ) { v[i] += rhs[i]; matvec( v, x, a, i, n ); } omp デバイス毎にチューニング 複数の異なるtarget 用に clause を指示する device_type(target) … 例えば、NVIDIA用と AMD Radeon用に mapping を変える

(28)

Global dataのハンドリング

float a[1000000];

#pragma acc routine worker extern void matvec(…);

#pragma acc parallel loop for( i = 0; i < m; ++i ) { matvec( v, x, i, n ); }

extern float a[];

#pragma acc routine worker

void matvec ( float* v, float* x,int i, int n ) { #pragma acc loop worker

for( int j = 0; j < n; ++j ) x[i] += a[i*n+j]*v[j]; }

分離コンパイル機能の追加により

ルーチン間に跨る「グローバル変数」の データ管理をサポートする必要がある。

declare文を使う4つの方法

(29)

① Global Static dataのハンドリング declare文

float a[1000000];

#pragma acc declare create(a) #pragma acc routine worker extern void matvec(…);

#pragma acc parallel loop for( i = 0; i < m; ++i ) { matvec( v, x, i, n );

}

extern float a[];

#pragma acc declare create(a) #pragma acc routine worker

void matvec ( float* v, float* x,int i, int n ) { #pragma acc loop worker

for( int j = 0; j < n; ++j ) x[i] += a[i*n+j]*v[j]; } 広域変数を宣言した後にdirectiveを指定 declare create(a) ・static dataをホストとデバイス両方に生成 ・ホストとデバイス間の明示的なデータ同期は update directive を使用して維持する declare文は routineの「宣言セクション」で使用 プログラム、ルーチン内のデータ領域等 で implicit に visible copy を生成

(30)

② Global Pointer のハンドリング declare文

float *a;

#pragma acc declare create(a) #pragma acc routine worker extern void matvec(…);

#pragma acc parallel loop \ copyin(a[0:n*m])

for( i = 0; i < m; ++i ) { matvec( v, x, i, n );

}

extern float *a;

#pragma acc declare create(a) #pragma acc routine worker

void matvec ( float* v, float* x,int i, int n ) { #pragma acc loop worker

for( int j = 0; j < n; ++j ) x[i] += a[i*n+j]*v[j]; } ポインタを宣言した後にdirectiveを指定 declare create(a) ・staticにポインタをホストとデバイス両方に生成 ・copyはユーザの責任で行う ・data clause中にcopy等を明示するとデバイス にデータ割付とコピーを行うコードを生成 ホスト側の割付、データ管理は ユーザの責任で行う

(31)

③ Global dataのハンドリング declare link節

float a[1000000];

#pragma acc declare link(a) #pragma acc routine worker extern void matvec(…);

#pragma acc parallel loop \ copyin(a[0:n*m])

for( i = 0; i < m; ++i ) { matvec( v, x, i, n );

}

extern float a[];

#pragma acc declare link(a) #pragma acc routine worker

void matvec ( float* v, float* x,int i, int n ) { #pragma acc loop worker

for( int j = 0; j < n; ++j ) x[i] += a[i*n+j]*v[j]; } link ()の引数は必ず、global 変数 declare link(a) ・ホスト上にデータ生成 ・デバイス上のデータへのリンク生成 ・「data clause」中にcopy等を明示する時だけ デバイスにデータ割付とコピーを行うコードを 生成

(32)

④ device_resident in declare文

float a[1000000];

#pragma acc declare device_resident(a) #pragma acc routine worker

extern void matvec(…); …

#pragma acc parallel loop for( i = 0; i < m; ++i ) { matvec( v, x, i, n );

}

extern float a[];

#pragma acc declare device_resident(a) #pragma acc routine worker nohost

void matvec ( float* v, float* x,int i, int n ) { #pragma acc loop worker

for( int j = 0; j < n; ++j ) x[i] += a[i*n+j]*v[j]; } declare device_resident(a) ・static dataをデバイス上のみに生成 ・ホスト側には a[ ] は生成されない 他に、 declare link( … ) 変数を宣言した後にdirectiveを指定 device上のみで動作、“nohost”が必要

(33)

“enter data” と “exit data” 構文

#pragma acc data copyin(a[0:n]) \ create(b[0:n]) {

… 構造化ブロック ….. }

#pragma acc enter data copyin(a[0:n]) \ create(b[0:n])

#pragma acc exit data delete(a[0:n])

#pragma acc exit data copyout(b[0:n]) データ領域の開始 ”enter” データ領域の終了 ”exit”

Data lifetime

を自由に設定する

OpenACC 1.0 では、「構造化ブロック」の前後 にデータ領域を指定するのみ

を任意の場所に

(34)

Unstructured data lifetimes

#pragma acc data copyin(a[0:n]) \ create(b[0:n]) { … 構造化ブロック ….. } void init (…) { …

#pragma acc enter data copyin(a[0:n]) \ create(b[0:n]) … } … void fini (…) { …

#pragma acc exit data copyout(b[0:n]) … } init ルーチンの中で ”enter”

Data lifetime

を自由に設定する

任意の場所に! fini ルーチンの中で ”exit”

(35)

新しい data API ルーチンの提供

• acc_copyin ( ptr, bytes ) • acc_create ( ptr, bytes ) • acc_copyout ( ptr, bytes ) • acc_delete ( ptr, bytes ) • acc_is_present ( ptr, bytes ) • acc_update_device ( ptr, bytes ) • acc_update_local ( ptr, bytes ) • acc_deviceptr ( ptr ) • acc_hostptr ( devptr )

• acc_map_data ( devptr, hostptr, bytes ) • acc_unmap_data ( hostptr )

data directive 構文の copy 節等の機能が、

APIルーチンとして提供

(36)

loop構文

OpenACC並列3階層をより厳密に整理

gangループ : gangループを含んではならない : 一番外側ループへの適用とする workerループ : gang、workerループを含んではならない vectorループ : gang、worker、vectorループを含んではならない : 一番内側ループへの適用とする autoの新設 : コンパイラが選択する

gang / worker / vector の実行モードの用語を明確に定義

gang redundant vs. gang partitioned mode

worker single vs. worker partitioned mode vector single vs. vector partitioned mode

(37)

Nested loops における tiling

!$acc parallel !$acc loop gang do i = 1, n

!$acc loop vector do j = 1, m

a(j,i) = (b(j-1,i)+b(j+1,i)+ & b(j,i-1)+b(j,i+1))*0.25 enddo

enddo

!$acc end parallel arallel

!$acc parallel

!$acc loop tile(64, 4) gang vector do i = 1, n

do j = 1, m

a(j,i) = (b(j-1,i)+b(j+1,i)+ b(j,i-1)+b(j,i+1))*0.25 enddo

enddo

!$acc end parallel

ループのタイル化

64 x 4 タイルのworker構成を gang 間で並列に実行 tile clause (64 x 4) 内側ループ (j) 外側ループ (i) • 2次元における分割化指示 • cacheの有効利用

(38)

OpenACC API 機能向上

様々な OS 、様々なホスト、様々なデバイス上で使用可能とする

出来得る限り、実行部分を「デバイス」側で可能にする

プログラミングの自由度を高めてゆくこと

The OpenACC™ Application Programming Interface (OpenACC API) for offloading programs written in C, C++ and Fortran programs

from a host CPU to an attached accelerator device

(39)

PGI OpenACC 機能ロードマップ(予定)

2014

2012 7月 2013 7月

CUDA 4.2 CUDA 5.0 CUDA 5.x

Kepler AMD Radeon NVIDIA

Maxell Xeon Phi Unstructured Data lifetimes OpenACC 2.0 AMD Radeon/APU Acc Func Call Nested Acc Compute OpenACC 1.0 Xeon Phi OpenACC 2.0 NVIDIA OpenACC AMD Radeon ACC Fortran texture Multi-device improve C++ OpenACC OpenACC 2.0 仕様決定 Code Generation Tuning

2.0 取込 対応 プラットフォーム ※予告なしに変更することがあります AMD APU 機能

(40)
(41)

Copyright 2013 SofTek Systems Inc.

All Rights Reserved.

参照

関連したドキュメント

ァルベシ.Martini02ニハー側ノ肺動脈幹或ハ両側ノ第1分枝二於ケル栓塞ニョリ数分ニシ

ベクトル計算と解析幾何 移動,移動の加法 移動と実数との乗法 ベクトル空間の概念 平面における基底と座標系

日頃から製造室内で行っていることを一般衛生管理計画 ①~⑩と重点 管理計画

N2b 同側の多発性リンパ節転移で最大径が 6cm 以下かつ節外浸潤なし N2c 両側または対側のリンパ節転移で最大径が 6cm 以下かつ節外浸潤なし

1-1 睡眠習慣データの基礎集計 ……… p.4-p.9 1-2 学習習慣データの基礎集計 ……… p.10-p.12 1-3 デジタル機器の活用習慣データの基礎集計………

『国民経済計算年報』から「国内家計最終消費支出」と「家計国民可処分 所得」の 1970 年〜 1996 年の年次データ (

ON Semiconductor makes no warranty, representation or guarantee regarding the suitability of its products for any particular purpose, nor does ON Semiconductor assume any

5.2 5.2 1)従来設備と新規設備の比較(1/3) 1)従来設備と新規設備の比較(1/3) 特定原子力施設