User-defined Migration Rules¶
Intel® DPC++ Compatibility Tool uses migration rules to migrate CUDA* code to SYCL* code. There are three categories of migration rules used by the tool:
Default migration rules. A set of built-in migration rules used by the Intel® DPC++ Compatibility Tool for all migrations.
Optional predefined migration rules. A set of predefined migration rules that can optionally be used for migration. Available predefined migration rules are in the extensions/opt_rules folder on the installation path of the Intel® DPC++ Compatibility Tool.
User-defined migration rules. Custom migration rules defined by the user. User-defined migration rules extend the migration capability of the Intel® DPC++ Compatibility Tool and can target the migration of specific CUDA syntax to SYCL syntax.
Specify Migration Rule Files¶
To specify a predefined or user-defined migration rule file for use in migration,
use the –rule-file
command line option with your migration command.
The –rule-file
option can be used multiple times with a single command to
specify multiple migration rule files. For example:
dpct sample.cu --rule-file=rule_file1.YAML --rule-file=rule_file2.YAML
See the Command Line Options Reference for additional information.
Write User-defined Migration Rules¶
Migration rules are specified in YAML files. To define a rule, use the following <key>: <value> pairs:
Key |
Value |
Description |
---|---|---|
Rule |
String value |
Required. Specifies the unique name of the rule. |
Priority |
|
Required. Specifies the priority of the rule: |
Kind |
|
Required. Specifies the rule type:
|
In |
String value |
Specifies the target macro or function name in the input source code. |
Out |
String value |
Required. Specifies the target macro or function call format in the output source code. |
Includes |
List of header files |
Required. Specifies the header files which should be included in the output source code. The value can be an empty list. |
A single rule file may contain multiple migration rules.
For example, the following user-defined migration rule file defines two rules:
--- # [YAML syntax] Begin the document
- Rule: rule_forceinline # [Required] Unique rule name
Kind: Macro # [Required] Type of rule [Macro | API]
Priority: Takeover # [Required] Rule priority [Takeover | Default | Fallback]
In: __forceinline__ # [Required] Target macro name in the input source code
Out: inline # [Required] Migrated name of the macro in output source code
Includes: ["header1.h", "\"header2.h\""] # [Required] List of header file names which the new macro depends on, can be an empty list
- Rule: rule_foo # [YAML syntax] "-" Denotes the start of another rule
Kind: API
Priority: Takeover
In: foo # [Required] Target function name in the input source code
Out: $type_name_of($2) *new_ptr = bar($deref($1)) # [Required] Format form of migrated result in output source code
Includes: ["<header3>"]
... # [YAML syntax] End the document
The first rule migrates
__forceinline__
in the input source code toinline
in the output source code.The second rule migrates any function call
foo(…)
in the input source code to a function calledbar(…)
in output source code.
Grammar for Out Key in a User-defined API Migration Rule¶
To describe the value format for the Out
key in a migration rule of
Kind: API
, use the following Backus-Naur form grammar:
OutValue::= Token | Token OutValue # OutValue is the value for the “out” key
Token::= AnyString | Keyword # AnyString is a string provided by the user
Keyword::= ArgIndex
| $queue # Represents the queue string
| $context # Represents the context string
| $device # Represents the device string
| $deref(ArgIndex) # The dereferenced value of the argument
| $type_name_of(ArgIndex) # The type name of the argument
| $deref_type(ArgIndex) # The dereferenced type name of the argument
| $addr_of(ArgIndex) # The address of the argument
ArgIndex::= $Int # Int should be a greater than zero integer
The following scenario describes how the tool makes use of a user-defined migration rule that uses this grammar to migrate code.
Consider the following user-defined API migration rule:
- Rule: rule_foo
Kind: API
Priority: Takeover
In: foo
Out: $type_name_of($2) new_ptr = bar($deref($1), $3)
Includes: [“<header3>”]
If the input source code contains a function call that matches the rule, the
tool parses the value of the In
and Out
keys and builds a keyword mapping
between the input and output source code. For example, with input source code:
int *ptr, *ptr2;
foo(ptr, ptr2, 30);
The tool creates the following mapping:
Keyword |
Input Source Code Match |
Migration Result |
---|---|---|
|
|
|
|
|
|
|
|
|
|
N/A |
|
|
N/A |
|
Using this mapping, the tool migrates the input source code into the following output source code:
int *ptr, *ptr2;
int * new_ptr = bar(*ptr, 30);