pragma SDS data copy

Description

Thepragma SDS data copy | zero_copymust be specified immediately preceding a function declaration, or immediately preceding other#pragma SDSbound to the function declaration.

Important:The COPYpragma and the ZERO_COPYpragma are mutually exclusive and should not be specified together on the same object.

TheCOPYpragma implies that data is explicitly copied between the host processor memory and the hardware function. A suitable data mover performs the data transfer.SeeImproving System Performancefor more information.

TheZERO_COPYmeans that the hardware function accesses the data directly from shared memory through an AXI master bus interface.

Important:By default, the SDSoC compiler assumes the COPYpragma for an array argument, meaning the data is explicitly copied from the processor to the accelerator via a data mover.

Syntax

The syntax for this pragma is:
#pragma SDS data copy|zero_copy(ArrayName[:])

Where:

  • ArrayName[:]specifies the function parameter or argument to assign the pragma to, and the array dimension and data transfer size.
  • ArrayName: must be one of the formal parameters of the function definition, not from the prototype (where parameter names are optional) but from the function definition.
  • : Optionally specifies the number of elements from the first element in the array. It must be specified as a compile-time constant.
    Important:The value is currently ignored, and should be specified as 0.
  • : Specifies the number of elements transferred from the array for the specified dimension. It can be an arbitrary expression as long as the expression can be resolved at runtime inside the function.
    Tip:As shown in the examples below, can be a C arithmetic expression involving other scalar arguments of the same function.
  • For a multi-dimensional array, each dimension should be separately specified. For example, for a 2-dimensional array, use:
    pragma SDS data copy(ArrayName[offset_dim1:length1][offset_dim2:length2])
  • Multiple arrays can be specified in the same pragma, using a comma separated list. For example, use:
    pragma SDS data copy(ArrayName1[offset1:length1], ArrayName2[offset2:length2])
  • The[:]argument is optional, and is only needed if the data transfer size for an array cannot be determined at compile time. When this is not specified, theCOPYorZERO_COPYpragma is only used to select between copying the memory to/from the accelerator through a data mover versus directly accessing the processor memory by the accelerator. To determine the array size, the SDSoC compiler analyzes the callers to the accelerator function to determine the transfer size based on the memory allocation APIs for the array, for examplemallocorsds_alloc. If the analysis fails, it checks the argument type to see if the argument type has a compile-time array size and uses that size as the data transfer size. If the data transfer size cannot be determined, the compiler generates an error message so that you can specify the data size with[:]. If the data size is different between the caller and callee, or different between multiple callers, the compiler also generates an error message so that you can correct the source code or use this pragma to override the compiler analysis.

Example 1

The following example applies the COPYpragma to both the "A" and "B" arguments of the accelerator function fooright before the function declaration. Notice the option is specified as an expression, size*size:
#pragma SDS data copy(A[0:size*size], B[0:size*size]) void foo(int *A, int *B, int size) { ... }
The SDSoC system compiler will replace the body of the function foowith accelerator control, data transfer, and data synchronization code. The following code snippet shows the data transfer part:
void _p0_foo_0(int *A, int *B, int size) { ... cf_send_i(&(_p0_swinst_foo_0.A), A, (size*size) * 4, &_p0_request_0); cf_receive_i(&(_p0_swinst_foo_0.B), B, (size*size) * 4, &_p0_request_1); ... }
As shown above, the offset value size*sizeis used to tell the SDSoC runtime the number of elements of arrays "A" and "B".
Tip:The cf_send_iand cf_receive_ifunctions require the number of bytes to transfer, so the compiler will multiply the number of elements specified by with the number of bytes for each element (4 in this case).

Example 2

The following code snippet shows an example of applying the ZERO_COPYpragma instead of the COPYpragma above:
#pragma SDS data zero_copy(A[0:size*size], B[0:size*size]) void foo(int *A, int *B, int size)
The body of function foobecomes:
void _p0_foo_0(int *A, int *B, int size) { ... cf_send_ref_i(&(_p0_swinst_foo_0.A), A, (size*size) * 4, &_p0_request_0); cf_receive_ref_i(&(_p0_swinst_foo_0.B), B, (size*size) * 4, &_p0_request_1); ... }

Thecf_send_ref_iandcf_receive_ref_ifunctions only transfer the reference or pointer of the array to the accelerator, and the accelerator accesses the processor memory directly.

Example 3

The following example shows a ZERO_COPY pragma with multiple arrays specified to generate a direct memory interface with DDR and the hardware function:
#pragma SDS data zero_copy(in1[0:mat_dim*mat_dim], in2[0:mat_dim*mat_dim], out[0:mat_dim*mat_dim]) void matmul_partition_accel(int *in1, // Read-Only Matrix 1 int *in2, // Read-Only Matrix 2 int *out, // Output Result int mat_dim); // Matrix Dim (assumed only square matrix) { ... }

Example 4

The following code snippet illustrates a common mistake: using an argument name in the function declaration that is different from the argument name used in the function definition:
"foo.h" #pragma SDS data copy(in_A[0:1024]) void foo(int *in_A, int *out_B) "foo.cpp" #include "foo.h" void foo(int *A, int *B) { ... }
Any C/C++ compiler will ignore the argument name in the function declaration, because the C/C++ standard makes the argument name in the function declaration optional. Only the argument name in the function definition is used by the compiler. However, the SDSoC compiler will issue a warning when trying to apply the pragma:
WARNING: [SDSoC 0-0] Cannot find argument in_A in accelerator function foo(int *A, int *B)

See Also

  • SDSoC Environment Optimization Guide(UG1235)
  • SDSoC Environment User Guide(UG1027)