数値 Maple プロシージャからのネイティブコードへのコンパイル
Compiler:-Compile - 数値 Maple プロシージャのコンパイル
|
使い方
|
|
Compiler:-Compile( p, opts )
|
|
パラメータ
|
|
p
|
-
|
{procedure,list(procedure)}; Maple のプロシージャまたはプロシージャのリスト
|
opts
|
-
|
オプション; trace=true/false, optimize=true/false よび warnings=true/false のいずれかを指定
|
|
|
|
|
説明
|
|
•
|
Compiler:-Compile コマンドは、Maple プロシージャの限定サブセットをネイティブコードにコンパイルして (詳細については後述します) コンパイル済みプロシージャを返します。Compiler モジュールはパッケージではありません。
|
•
|
一般に、Compiler の使用では、十分に長時間実行してコンパイルのオーバーヘッドを正当化するか、頻繁に呼び出してオーバーヘッドを分割するなどの場合にプロシージャのパフォーマンスが向上します。
|
•
|
特殊な用途の CodeGeneration をバックエンドで使用すると変換が行われます。Maple のプロシージャは C 言語コードに変換され、それから外部の C コンパイラでコンパイルされます。その後コンパイルされたコードは外部の呼び出し機能を使用して Maple に動的にリンクし、Maple で呼び出し可能なプロシージャが生成されます。これが該当する入力で呼び出されると、コンパイルされたコードが起動します。コンパイルされたコードからは解釈のオーバーヘッドが大幅に軽減されるため、多くの場合、evalhf 下で実行した場合以上にコンパイルプロシージャの実行速度が速くなります。
|
|
例外処理 (例外を単にレイズする場合は除く) は変換できません。
|
|
配列を返すか、新しい配列を割り当てるプロシージャは変換できません。
|
|
不十分な型情報がコンパイル時に取得される可能性がある他のプロシージャを呼び出すプロシージャは変換できません。
|
|
整数データは使用中のハードウェア単語サイズの整数に制限されます。より大きい整数を生成する計算を実行するとオーバーフロー例外になります。
|
|
複素数浮動小数点の演算を含む浮動小数点演算は、ハードウェアの精密度に全面的に準じて実行されます( evalhf と同様)。
|
|
サポート対象のすべてのハードウェアでは 2 を基数とした浮動小数点を使用する算術方式を採用していますが、Maple ソフトウェアの浮動小数点系は基数が 10 の系です。基数に大きく依存する数値計算では、基数の違いが結果を左右します。
|
•
|
単独のプロシージャまたはプロシージャを連ねた形式のリストは、Compiler:-Compile コマンドに最初の引数として渡される場合があります。最初の引数がリストの場合、Compiler:-Compile コマンドはこのリストを自動的に写像して、コンパイルしたプロシージャのリストを返します。
|
|
|
外部の C コンパイラ
|
|
•
|
コンパイルツールチェーンの重要なコンポーネントの一つである外部 C コンパイラは C コードの生成で使用します。
|
•
|
32 ビット Windows プラットフォームで、OpenWatcom C コンパイラは放出された C コードのコンパイルで使用されます。Maple から Windows 版 OpenWatcom コンパイラが配布されています。
|
•
|
64 ビット Windows プラットフォームでは、利用可能な Microsoft コンパイラがある場合、これによって放出された C コードがコンパイルされます。
|
•
|
これ以外のすべてのシステム (UNIX や Mac OSX) では、GNU C コンパイラで放出された C コードがコンパイルされます。GNU C コンパイラは、Maple では提供しておらず、システムに搭載されていない場合は、別途インストールする必要があります。数値コードのコンパイル機能は、プログラム検索パスにある "gcc'' コマンドに依存します。(環境変数 "PATH'')
|
•
|
infolevel[Compiler] を正の値 (1 または 3) に設定するとコンパイラの動作状況に関する情報を取得できます。
|
•
|
32 ビットの Windows プラットフォームでは、実行される Maple プロセスのカレントディレクトリに対して Compiler からの書き込みが可能でなければならない点に注意してください。
|
|
|
オプション
|
|
•
|
Compiler:-Compile コマンドは、コードの生成方法に関するいくつかのオプションを許可します。
|
•
|
trace オプションを使用すると、コンパイル済みプロシージャの実行を追跡できます。これは通常の Maple プロシージャの trace オプションと同様のオプションです。trace オプションは、trace = true (または単に trace) とするか、 Compiler:-Compile コマンドの引数として trace = false を指定する形式で記述できます。デフォルトでは追跡は無効になっています。
|
•
|
Compiler:-Compile コマンドのオプションとして warnings = true (または単に warnings) を指定すると、変換中に追加の警告が可能になります。追加の警告を無効にする (デフォルト) には、warnings = false と指定します。
|
•
|
Maple が入力プロシージャの最適化を試みるリクエストは、optimize オプションを optimize = true (または単に optimize) または optimize = false の形式で指定します。現時点では、codegen[optimize] を通じてこれを渡すことで変換前にコードが最適化されます。最適化はデフォルトでは実行されません。
|
|
|
一時ファイルの格納
|
|
•
|
コンパイラは実行時にいくつかの一時ファイルを生成します。コードがコンパイルされた共有ライブラリまたは DLL は、各ユーザーおよびプロセス固有の一時ディレクトリに保存されます。これらのファイルは、ファイルが作成された Maple セッション中は保持されることになります。このような一時ディレクトリを置くディレクトリを管理するには、システムの環境変数 MAPLE_TEMPDIR を使用しますが、この環境変数は書き込み許可があるディレクトリ (またはフォルダ) に設定する必要があります。
|
•
|
システムの環境変数 MAPLE_TEMPDIR が未定義であるか、使用できない場合 (存在しないか書き込み可能でないなどの場合)、プラットフォーム依存型アルゴリズムを使用してファイルの保存に使用できるディレクトリを検索します。他のディレクトリが見つからない場合は、現在の作業ディレクトリを使用します。Windows では、作業ディレクトリを除き、使用される一時ディレクトリの名前にはスペースが許可されない場合があるので注意が必要です。作業ディレクトリの場合は相対パス名が OpenWatcom コンパイラに渡されます。
|
|
|
ランタイムサポート
|
|
•
|
コンパイルされたコードは、サポートされる機能のランタイムライブラリにアクセスできます。ランタイムライブラリは、コンパイルされたコードの実行を助けるいくつものユーティリティが用意されています。また、evalhf コマンドと共有される演算機能のライブラリとしても使用できます。さらに、整数を扱うことができる Maple コマンドのハードウェア整数バージョンが、print と type の限定バージョンとして用意されています。
|
•
|
ランタイムライブラリで利用可能な組み込み演算関数には以下の種類があります。
|
sin
|
cos
|
tan
|
csc
|
sec
|
cot
|
arcsin
|
arccos
|
arctan
|
arccsc
|
arcsec
|
arccot
|
sinh
|
cosh
|
tanh
|
csch
|
sech
|
coth
|
arcsinh
|
arccosh
|
arctanh
|
arccsch
|
arcsech
|
arccoth
|
exp
|
ln
|
log10
|
erf
|
erfc
|
GAMMA
|
lnGAMMA
|
Dirac
|
Heaviside
|
ceil
|
floor
|
trunc
|
frac
|
round
|
signum
|
csgn
|
Re
|
Im
|
argument
|
conjugate
|
|
|
|
•
|
また、次の限定バージョンの Maple プロシージャがランタイムライブラリに含まれています。
|
print
|
lprint
|
printf
|
irem
|
iquo
|
igcd
|
modp
|
mods
|
mod
|
abs
|
isqrt
|
type
|
|
|
•
|
type ランタイム関数で認識される型には以下の種類があります。
|
positive
|
negative
|
nonpositive
|
nonnegative
|
posint
|
negint
|
nonposint
|
nonnegint
|
poszero
|
negzero
|
pos_infinity
|
neg_infinity
|
real_infinity
|
infinity
|
undefined
|
even
|
odd
|
integer
|
numeric
|
realcons
|
float
|
finite
|
|
|
|
|
•
|
モジュール形式の演算がサポートされています。加算、乗算、除算 (単位別)、累乗、論理否定の各種演算はオーバーフローしません。環境変数 mod がランタイムに実装されます。
|
•
|
ランタイムライブラリには、一覧した組み込みプロシージャの限定バージョンだけが含まれています。これらのプロシージャはハードウェアデータ型 (整数、浮動小数点、複素数浮動小数点) のみ処理できます。整数の値を使用するランタイムプロシージャは、infinity または -infinity を返すことも許容もできません。整数の計算でマシン語のサイズがオーバーフローすると例外となり、これはオーバーフローがレイズされることを意味します。これは整数の演算にも適用されます。ランタイムの type プロシージャは上記に一覧したどの型も認識せず、構造体型やユーザー定義の型はいずれもサポートされません。
|
|
|
大規模プロシージャの管理
|
|
•
|
非常に長大な式を含むプロシージャのコンパイルでは、C コードの生成と生成されたコードでの C コンパイラの実行の両方でかなりのオーバーヘッドが必要となる場合があります。以下のような問題が発生した場合は、optimize オプションの使用を検討してみてください。
|
|
Compiler で C コードを生成するのにかなりの長時間を要する。
|
|
外部の C コンパイラで生成後の C コードをコンパイルするのにかなりの長時間を要する。
|
|
生成後の C コードをコンパイルすると外部の C コンパイラでメモリ不足になる。
|
|
|
配列のサポート
|
|
•
|
配列はコンパイル対象のプロシージャのパラメータとしてのみ表示することができます。グローバル的または語彙的に範囲指定された一部の変数に対するサポートはあるものの、スカラ値の数量に限定されており、それらの有効な型を決定するための十分な型情報がコンパイルされるプロシージャの実行時に必要です。
|
•
|
多次元配列 (行列など) がサポートされます。通常、パラメータ型の説明に Arrays の次元情報を提供するのは難しいことから、コンパイルされるプロシージャの本体にアクセスする方法によって、CodeGeneration パッケージが Array パラメータの次元数を決定します。コンパイルされるプロシージャの本体で Array パラメータがアクセスされず、パラメータ型の説明に次元情報が指定されない場合、Array パラメータは 1 次元とみなされます。
|
|
|
再帰のサポート
|
|
•
|
Compiler では再帰プロシージャがサポートされます。コンパイルするコードを再帰的に動作させるには、プロシージャが割り当てられている名前ではなく、暗黙パラメータの procname を通じて再帰呼び出しを 必ず 行う必要があります (厳密には、コンパイル対象であるかどうかにかかわらず、Maple の再帰プロシージャが再帰的に動作するためには常にこの方法でコーディングする必要があります)。
|
•
|
コンパイル中に、末尾再帰呼び出しが検出され、繰り返し変換されます。したがって、末尾再帰プロシージャは非常に高速なコードにコンパイルされます。
|
|
|
セキュアモードでの操作
|
|
•
|
コンパイラは一時ファイルを作成して外部プロセスを実行するため、コマンドラインで -z オプションを使用して Maple をセキュアモードで起動したり、GUI のオプションメニューを通じて拡張セキュリティ機能を有効にしている場合は、コンパイラを利用できません。
|
|
|
プロシージャオプション 'autocompile'
|
|
•
|
Maple プロシージャには、autocompile というオプションを指定できる場合があります。このオプションにより、カーネルは最初の実行で、プロシージャからネイティブコードへのコンパイルを試みます。コンパイルが成功すると、プロシージャを呼び出した名前にコンパイルされたプロシージャの値が再び割り当てられます。実際には元のプロシージャからコンパイルコードを実行するプロシージャに置き換わります。
|
|
|
例
|
|
>
|
p := proc( x :: float ) :: float; 2.3 * x end proc:
|
>
|
|
>
|
|
| (13.1) |
>
|
p := proc( n :: posint, x :: float ) :: float;
local i :: integer, s :: float;
s := 0.0;
for i from 1 to n do
s := s + x / i
end do;
s
end proc:
|
>
|
|
| (13.2) |
>
|
|
| (13.3) |
>
|
|
| (13.4) |
>
|
|
| (13.5) |
>
|
p := proc( n :: posint, a :: Array( datatype = float[ 8 ] ) )
local i::integer, s::float;
s := 0.0;
for i from 1 to n do
s := s + a[ i ]
end do;
s
end proc:
|
>
|
|
>
|
|
| (13.6) |
>
|
|
| (13.7) |
>
|
|
| (13.8) |
>
|
|
Error, (in cp) array index out of bounds
| |
>
|
|
| (13.9) |
次の「ハノイの塔問題」の実装例に示すように、再帰プロシージャを処理することができます。
>
|
HanoiMove := proc( a :: Array( 1 .. 4, datatype = integer[ 4 ] ),
numdisks :: posint,
frompeg :: posint, topeg :: posint )
local tmp;
if numdisks = 1 then
a[ frompeg ], a[ topeg ] := a[ frompeg ] - 1, 1 + a[ topeg ]
else
tmp := 6 - ( frompeg + topeg );
procname( a, numdisks - 1, frompeg, tmp );
procname( a, 1, frompeg, topeg );
procname( a, numdisks - 1, tmp, topeg )
end if
end proc:
|
>
|
|
| (13.10) |
| (13.11) |
複素数浮動小数点データがサポートされます。
>
|
p := proc( a :: Array( datatype = complex[8] ), n :: posint ) :: complex(extended_numeric);
local s, i;
s := 0.0 + 0.0*I;
for i from 1 to n do
s := s + arcsin( a[ i ] )
end do;
s
end proc:
|
>
|
|
>
|
|
>
|
|
| (13.12) |
追跡用のオプションを指定してコンパイル後のプロシージャを追跡できるようにします。
>
|
p := proc( n :: integer ) :: integer;
if n < 1 then
0
else
1 + procname( n - 1 )
end if
end proc:
|
>
|
|
>
|
|
| (13.13) |
autocompile オプションを使用すると、初回の呼び出しでプロシージャがコンパイルを試みるように指定できます。
>
|
Sort := proc( a :: Array( datatype = integer[ 4 ] ), n :: posint )
local i, j, m, tmp;
option autocompile;
for i from 1 to n do
m := i;
for j from 1 + i to n do
if a[ j ] < a[ m ] then
m := j
end if
end do;
a[ m ], a[ i ] := a[ i ], a[ m ]
end do
end proc:
|
>
|
|
| (13.14) |
>
|
|
| (13.15) |
>
|
|
| (13.16) |
以下の例は、モジュール式演算と語彙的に範囲指定されたパラメータのサポートの様子を示したものです。
>
|
p := proc( m :: posint )
proc( a :: integer, b :: integer ) ( a + b ) mod m end
end proc:
|
>
|
|
>
|
|
| (13.17) |
>
|
|
| (13.18) |
>
|
|
| (13.19) |
>
|
|
>
|
|
| (13.20) |
>
|
|
| (13.21) |
以下のようにオーバーロードしたプロシージャを使用すると、適切な入力ではコンパイルコードを実行するアルゴリズムを実装することができますが、他の入力では 解釈後の Maple コードにフェールバックします。
>
|
F := overload([
proc( s :: float, n :: integer[ 4 ] ) :: float;
local i;
option overload, autocompile;
userinfo( 1, "F", "using native code" );
sin( s / n ) # for small n, use native code
end proc,
proc( s :: float, n :: integer ) :: float;
local i;
option overload;
userinfo( 1, F, "using Maple software code" );
sin( s / n ) # for large n use Maple arithmetic
end proc,
proc( s :: algebraic, n :: algebraic )
'F( args )' # return a symbolic result
end proc,
NULL]):
|
>
|
|
>
|
|
| (13.22) |
>
|
|
| (13.23) |
>
|
|
| (13.24) |
もう一つ例を示します。
>
|
|
>
|
F := overload([
proc( a :: Array( datatype = integer[ 4 ] ), n :: posint, m :: integer[ 4 ] ) :: integer[ 4 ];
option overload, autocompile;
local i, s;
userinfo( 1, F, "using small modulus implementation" );
s := 0;
for i from 1 to n do
s := ( s + a[ i ] ) mod m
end do;
s
end proc,
proc( a :: Array, n :: posint, m :: integer ) :: integer;
option overload;
local i, s;
userinfo( 1, F, "using large modulus implementation" );
s := 0;
for i from 1 to n do
s := ( s + a[ i ] ) mod m
end do;
s
end proc,
NULL]):
|
>
|
|
>
|
|
>
|
|
F: "using small modulus implementation"
| |
| (13.25) |
>
|
|
>
|
|
F: "using large modulus implementation"
| |
| (13.26) |
`-z' オプションを指定して Maple を起動すると、Compiler は使用できず、次のような例外がレイズされます。
>
|
|
Error, (in Compiler) this command is not available in secure mode
|
|
|
|
|
参照
|
|
Array, codegen[optimize], CodeGeneration, CodeGeneration,TranslationDetails, define_external, evalhf, mod, modp, mods, procname, RandomTools
|
|