Skip to main content

cutensorCreateElementwiseTrinary

Function cutensorCreateElementwiseTrinary 

Source
pub unsafe extern "C" fn cutensorCreateElementwiseTrinary(
    handle: cutensorHandle_t,
    desc: *mut cutensorOperationDescriptor_t,
    descA: cutensorTensorDescriptor_t,
    modeA: *const i32,
    opA: cutensorOperator_t,
    descB: cutensorTensorDescriptor_t,
    modeB: *const i32,
    opB: cutensorOperator_t,
    descC: cutensorTensorDescriptor_t,
    modeC: *const i32,
    opC: cutensorOperator_t,
    descD: cutensorTensorDescriptor_t,
    modeD: *const i32,
    opAB: cutensorOperator_t,
    opABC: cutensorOperator_t,
    descCompute: cutensorComputeDescriptor_t,
) -> cutensorStatus_t
Expand description

This function creates an operation descriptor that encodes an elementwise trinary operation.

Said trinary operation has the following general form:

$$ D_{\Pi^C(i_0,i_1,…,i_n)} = \Phi_{ABC}(\Phi_{AB}(\alpha op_A(A_{\Pi^A(i_0,i_1,…,i_n)}), \beta op_B(B_{\Pi^B(i_0,i_1,…,i_n)})), \gamma op_C(C_{\Pi^C(i_0,i_1,…,i_n)})) $$ Where

  • A,B,C,D are multi-mode tensors (of arbitrary data types).
  • $\Pi^A, \Pi^B, \Pi^C$ are permutation operators that permute the modes of A, B, and C respectively.
  • $op_{A},op_{B},op_{C}$ are unary element-wise operators (e.g., IDENTITY, CONJUGATE).
  • $\Phi_{ABC}, \Phi_{AB}$ are binary element-wise operators (e.g., ADD, MUL, MAX, MIN).

Notice that the broadcasting (of a mode) can be achieved by simply omitting that mode from the respective tensor.

Moreover, modes may appear in any order, giving users a greater flexibility. The only restrictions are:

  • modes that appear in A or B must also appear in the output tensor; a mode that only appears in the input would be contracted and such an operation would be covered by either cutensorContract or cutensorReduce.
  • each mode may appear in each tensor at most once.

Input tensors may be read even if the value of the corresponding scalar is zero.

Examples:

  • $D_{a,b,c,d} = A_{b,d,a,c}$
  • $D_{a,b,c,d} = 2.2 \* A_{b,d,a,c} + 1.3 \* B_{c,b,d,a}$
  • $D_{a,b,c,d} = 2.2 \* A_{b,d,a,c} + 1.3 \* B_{c,b,d,a} + C_{a,b,c,d}$
  • $D_{a,b,c,d} = min((2.2 \* A_{b,d,a,c} + 1.3 \* B_{c,b,d,a}), C_{a,b,c,d})$

Call cutensorElementwiseTrinaryExecute to perform the actual operation.

Please use cutensorDestroyOperationDescriptor to deallocated the descriptor once it is no longer used.

Supported data-type combinations are:

typeAtypeBtypeCdescCompute
cudaDataType_t::CUDA_R_16FcudaDataType_t::CUDA_R_16FcudaDataType_t::CUDA_R_16FCUTENSOR_COMPUTE_DESC_16F
cudaDataType_t::CUDA_R_16FcudaDataType_t::CUDA_R_16FcudaDataType_t::CUDA_R_16FCUTENSOR_COMPUTE_DESC_32F
cudaDataType_t::CUDA_R_16BFcudaDataType_t::CUDA_R_16BFcudaDataType_t::CUDA_R_16BFCUTENSOR_COMPUTE_DESC_16BF
cudaDataType_t::CUDA_R_16BFcudaDataType_t::CUDA_R_16BFcudaDataType_t::CUDA_R_16BFCUTENSOR_COMPUTE_DESC_32F
cudaDataType_t::CUDA_R_32FcudaDataType_t::CUDA_R_32FcudaDataType_t::CUDA_R_32FCUTENSOR_COMPUTE_DESC_32F
cudaDataType_t::CUDA_R_64FcudaDataType_t::CUDA_R_64FcudaDataType_t::CUDA_R_64FCUTENSOR_COMPUTE_DESC_64F
cudaDataType_t::CUDA_C_32FcudaDataType_t::CUDA_C_32FcudaDataType_t::CUDA_C_32FCUTENSOR_COMPUTE_DESC_32F
cudaDataType_t::CUDA_C_64FcudaDataType_t::CUDA_C_64FcudaDataType_t::CUDA_C_64FCUTENSOR_COMPUTE_DESC_64F
cudaDataType_t::CUDA_R_32FcudaDataType_t::CUDA_R_32FcudaDataType_t::CUDA_R_16FCUTENSOR_COMPUTE_DESC_32F
cudaDataType_t::CUDA_R_64FcudaDataType_t::CUDA_R_64FcudaDataType_t::CUDA_R_32FCUTENSOR_COMPUTE_DESC_64F
cudaDataType_t::CUDA_C_64FcudaDataType_t::CUDA_C_64FcudaDataType_t::CUDA_C_32FCUTENSOR_COMPUTE_DESC_64F

Remark

calls asynchronous functions, no reentrant, and thread-safe.

§Parameters

  • handle: Opaque handle holding cuTENSOR’s library context.
  • desc: This opaque struct gets allocated and filled with the information that encodes the requested elementwise operation.
  • descA: A descriptor that holds the information about the data type, modes, and strides of A.
  • modeA: Array (in host memory) of size descA->numModes that holds the names of the modes of A (e.g., if $A_{a,b,c}$ then modeA = {‘a’,’b’,’c’}). The modeA[i] corresponds to extent[i] and stride[i] w.r.t. the arguments provided to cutensorCreateTensorDescriptor.
  • opA: Unary operator that will be applied to each element of A before it is further processed. The original data of this tensor remains unchanged.
  • descB: A descriptor that holds information about the data type, modes, and strides of B.
  • modeB: Array (in host memory) of size descB->numModes that holds the names of the modes of B. modeB[i] corresponds to extent[i] and stride[i] of the cutensorCreateTensorDescriptor.
  • opB: Unary operator that will be applied to each element of B before it is further processed. The original data of this tensor remains unchanged.
  • descC: A descriptor that holds information about the data type, modes, and strides of C.
  • modeC: Array (in host memory) of size descC->numModes that holds the names of the modes of C. The modeC[i] corresponds to extent[i] and stride[i] of the cutensorCreateTensorDescriptor.
  • opC: Unary operator that will be applied to each element of C before it is further processed. The original data of this tensor remains unchanged.
  • descD: A descriptor that holds information about the data type, modes, and strides of D. Notice that we currently request descD and descC to be identical.
  • modeD: Array (in host memory) of size descD->numModes that holds the names of the modes of D. The modeD[i] corresponds to extent[i] and stride[i] of the cutensorCreateTensorDescriptor.
  • opAB: Element-wise binary operator (see $\Phi_{AB}$ above).
  • opABC: Element-wise binary operator (see $\Phi_{ABC}$ above).
  • descCompute: Determines the precision in which this operations is performed.

§Return value