Skip to main content

cutensorMgCreateTensorDescriptor

Function cutensorMgCreateTensorDescriptor 

Source
pub unsafe extern "C" fn cutensorMgCreateTensorDescriptor(
    handle: cutensorMgHandle_t,
    desc: *mut cutensorMgTensorDescriptor_t,
    numModes: u32,
    extent: *const i64,
    elementStride: *const i64,
    blockSize: *const i64,
    blockStride: *const i64,
    deviceCount: *const i32,
    numDevices: u32,
    devices: *const i32,
    type_: cudaDataType_t,
) -> cutensorStatus_t
Expand description

Create a tensor descriptor.

A tensor descriptor fully specifies the data layout of a (potentially) distributed tensor. It does so mainly through five pieces of data: The extent, the element stride, the block size, the block stride, and the device count.

The extent describes the total size of each tensor mode. For example, an 9 by 9 matrix would have an extent of 9 and 9.

The block size describes how the data is blocked. For example, with a block size of 4 by 2, there would be three blocks in the first and five blocks in the second mode.

4 x 24 x 21 x 2
4 x 24 x 21 x 2
4 x 24 x 21 x 2
4 x 24 x 21 x 2
4 x 14 x 11 x 1

The device count then describes how many devices the blocks are distributed across in that mode. A device count of 2 by 2, for example, would mean that the blocks are distributed across two devices in each mode, i.e., four devices total. The devices are aranged first along the first and then the second mode as follows:

Dev. 0Dev. 2
Dev. 1Dev. 3

In particular, device 0 would own the first, and third block in the first dimension, the first, third, and fifth block in the second dimension (so a total of six blocks), device 1 would own the first and third block in the first dimension, and the second and fourth block in the second dimension (four blocks total), device 2 would own the second block in the first dimension, and the first, third, and fifth block in the second dimension (for a total of three blocks), and, finally, device 3 would own the second block in the first dimension and the second and fourth block in the second dimension (for a total of two blocks).

Dev. 0Dev. 2Dev. 0
Dev. 1Dev. 3Dev. 1
Dev. 0Dev. 2Dev. 0
Dev. 1Dev. 3Dev. 1
Dev. 0Dev. 2Dev. 0

The element stride and block stride then describe how the blocks are laid out on the individual devices, i.e. the distance between elements and blocks in that mode. Finally, the devices array describes which device the blocks are mapped to. Here, it is permissible to specify cutensorMgHostDevice_t::CUTENSOR_MG_DEVICE_HOST to express that those blocks are located on the host. A tensor must either be located fully on-device or fully on-host.

Tensors may also be replicated, where the same tensor data is distributed across devices, or a mixture of replicated and distributed. Replication is expressed by setting numDevices to a value that is a multiple of the product of deviceCounts. At that point, the devices tensor is assumed to have an extra final mode across which the tensor is replicated. Replicated tensors can be used everywhere except as outputs for contractions. . Particularly, passing replicated tensors can unlock new optimizations that . are advantageous for problems that benefit from reduced communication.

 For instance, with devices = {0,1,2,3, 4,5,6,7} the tensor would be replicated
``` as follows:

|  |  |  |
| --- | --- | --- |
| Dev. 0 & 4 | Dev. 2 & 6 | Dev. 0 & 4 |
| Dev. 1 & 5 | Dev. 3 & 7 | Dev. 1 & 5 |
| Dev. 0 & 4 | Dev. 2 & 6 | Dev. 0 & 4 |
| Dev. 1 & 5 | Dev. 3 & 7 | Dev. 1 & 5 |
| Dev. 0 & 4 | Dev. 2 & 6 | Dev. 0 & 4 |

Remark

non-blocking, no reentrant, and thread-safe.

# Parameters

- `handle`: The library handle.
- `desc`: The resulting tensor descriptor.
- `numModes`: The number of modes.
- `extent`: The extent of the tensor in each mode (array of size `numModes`).
- `elementStride`: The offset (in linear memory) between two adjacent elements in each mode (array of size `numModes`), may be `NULL` for a dense tensor.
- `blockSize`: The size of a block in each mode (array of size `numModes`), may be `NULL` for an unblocked tensor (i.e., each mode only has a single block that is equal to its extent).
- `blockStride`: The offset (in linear memory) between two adjacent blocks in each mode (array of size `numModes`), may be `NULL` for a dense block-interleaved layout.
- `deviceCount`: The number of devices that each mode is distributed across in a block-cyclic fashion (array of size `numModes`), may be `NULL` for a non-distributed tensor.
- `numDevices`: The total number of devices that the tensor is distributed across (i.e., the product of all elements in `deviceCount` times how many devices it is replicated across).
- `devices`: The devices that the blocks are distributed across, in column-major order, i.e., stride 1 first (array of size `numDevices`).

# Return value

- [`cutensorStatus_t::CUTENSOR_STATUS_INVALID_VALUE`]: Some input parameters were invalid.
- [`cutensorStatus_t::CUTENSOR_STATUS_NOT_SUPPORTED`]: This layout or data type is not supported.
- [`cutensorStatus_t::CUTENSOR_STATUS_SUCCESS`]: The operation completed successfully.