Snitch Runtime
Loading...
Searching...
No Matches
dma.h File Reference

This file provides functions to program the Snitch DMA. More...

#include <string.h>
#include <math.h>

Go to the source code of this file.

Functions

uint32_t snrt_dma_start_1d (uint64_t dst, uint64_t src, size_t size, uint32_t channel)
 Start an asynchronous 1D DMA transfer with 64-bit wide pointers on a specific DMA channel.
 
uint32_t snrt_dma_start_1d (volatile void *dst, volatile void *src, size_t size, uint32_t channel=0)
 Start an asynchronous 1D DMA transfer using native-size pointers.
 
void snrt_dma_set_awuser (uint64_t field)
 Set AW user field of the DMA's AXI interface.
 
void snrt_dma_enable_multicast (uint64_t mask)
 Enable multicast for successive transfers.
 
void snrt_dma_enable_reduction (uint64_t mask, snrt_collective_opcode_t opcode)
 Enable reduction operations for successive transfers.
 
void snrt_dma_disable_multicast ()
 Disable multicast for successive transfers.
 
void snrt_dma_disable_reduction ()
 Disable reduction operations for successive transfers.
 
uint32_t snrt_dma_start_1d_reduction (uint64_t dst, uint64_t src, size_t size, uint64_t mask, snrt_collective_opcode_t opcode, uint32_t channel=0)
 Start an asynchronous reduction 1D DMA transfer with 64-bit wide pointers.
 
uint32_t snrt_dma_start_1d_reduction (uint64_t dst, uint64_t src, size_t size, snrt_comm_t comm, snrt_collective_opcode_t opcode, uint32_t channel=0)
 Start an asynchronous reduction 1D DMA transfer with 64-bit wide pointers.
 
uint32_t snrt_dma_start_1d_mcast (uint64_t dst, uint64_t src, size_t size, uint64_t mask, uint32_t channel=0)
 Start an asynchronous multicast 1D DMA transfer with 64-bit wide pointers.
 
uint32_t snrt_dma_start_1d_mcast (uint64_t dst, uint64_t src, size_t size, snrt_comm_t comm, uint32_t channel=0)
 Start an asynchronous multicast 1D DMA transfer with 64-bit wide pointers.
 
uint32_t snrt_dma_start_1d_reduction (volatile void *dst, volatile void *src, size_t size, uint64_t mask, snrt_collective_opcode_t opcode, uint32_t channel=0)
 Start an asynchronous reduction 1D DMA transfer using native-size pointers.
 
uint32_t snrt_dma_start_1d_mcast (volatile void *dst, volatile void *src, size_t size, uint64_t mask, uint32_t channel=0)
 Start an asynchronous multicast 1D DMA transfer using native-size pointers.
 
snrt_dma_txid_t snrt_dma_start_2d (uint64_t dst, uint64_t src, size_t size, size_t dst_stride, size_t src_stride, size_t repeat, uint32_t channel)
 Start an asynchronous 2D DMA transfer with 64-bit wide pointers.
 
uint32_t snrt_dma_start_2d (volatile void *dst, volatile void *src, size_t size, size_t dst_stride, size_t src_stride, size_t repeat, uint32_t channel=0)
 Start an asynchronous 2D DMA transfer using native-size pointers.
 
uint32_t snrt_dma_start_2d_mcast (uint64_t dst, uint64_t src, size_t size, size_t dst_stride, size_t src_stride, size_t repeat, uint32_t mask, uint32_t channel=0)
 Start an asynchronous, multicast 2D DMA transfer with 64-bit wide pointers.
 
uint32_t snrt_dma_start_2d_mcast (volatile void *dst, volatile void *src, size_t size, size_t dst_stride, size_t src_stride, size_t repeat, uint32_t mask, uint32_t channel=0)
 Start an asynchronous, multicast 2D DMA transfer using native-size pointers.
 
static uint32_t snrt_dma_busy (const uint32_t channel)
 Read DMA busy flag.
 
static uint32_t snrt_dma_would_block (const uint32_t channel)
 Read DMA would_block flag.
 
static void snrt_dma_wait (snrt_dma_txid_t txid, const uint32_t channel=0)
 Block until a DMA transfer finishes on a specific DMA channel.
 
static void snrt_dma_wait_all (const uint32_t channel=0)
 Block until a specific DMA channel is idle.
 
void snrt_dma_wait_all_channels (uint32_t num_channels)
 Block until the first num_channels channels are idle.
 
void snrt_dma_start_tracking ()
 Start tracking of dma performance region. Does not have any implications on the HW. Only injects a marker in the DMA traces that can be analyzed.
 
void snrt_dma_stop_tracking ()
 Stop tracking of dma performance region. Does not have any implications on the HW. Only injects a marker in the DMA traces that can be analyzed.
 
void snrt_dma_memset (void *ptr, uint8_t value, uint32_t len)
 Fast memset function performed by DMA.
 
snrt_dma_txid_t snrt_dma_load_1d_tile (volatile void *dst, volatile void *src, size_t tile_idx, size_t tile_size, uint32_t prec)
 Load a tile of a 1D array.
 
snrt_dma_txid_t snrt_dma_load_1d_tile_mcast (void *dst, void *src, size_t tile_idx, size_t tile_size, uint32_t prec, uint64_t mask)
 Load a tile of a 1D array.
 
snrt_dma_txid_t snrt_dma_reduction_load_1d_tile (void *dst, void *src, size_t tile_idx, size_t tile_size, uint32_t prec, uint64_t mask, snrt_collective_opcode_t opcode)
 Load a tile of a 1D array.
 
snrt_dma_txid_t snrt_dma_1d_to_2d (volatile void *dst, volatile void *src, size_t size, size_t row_size, size_t stride)
 Transfer and reshape a 1D array into a 2D array.
 
snrt_dma_txid_t snrt_dma_2d_to_1d (volatile void *dst, volatile void *src, size_t size, size_t row_size, size_t stride)
 Transfer and reshape a 2D array into a 1D array.
 
snrt_dma_txid_t snrt_dma_store_1d_tile (void *dst, void *src, size_t tile_idx, size_t tile_size, uint32_t prec)
 Store a tile to a 1D array.
 
snrt_dma_txid_t snrt_dma_load_2d_tile (void *dst, void *src, size_t tile_x1_idx, size_t tile_x0_idx, size_t tile_x1_size, size_t tile_x0_size, size_t full_x0_size, uint32_t prec, size_t tile_ld)
 Load a 2D tile of a 2D array.
 
snrt_dma_txid_t snrt_dma_load_2d_tile (void *dst, void *src, size_t tile_x1_idx, size_t tile_x0_idx, size_t tile_x1_size, size_t tile_x0_size, size_t full_x0_size, uint32_t prec)
 Load a 2D tile of a 2D array.
 
snrt_dma_txid_t snrt_dma_load_2d_tile_mcast (void *dst, void *src, size_t tile_x1_idx, size_t tile_x0_idx, size_t tile_x1_size, size_t tile_x0_size, size_t full_x0_size, uint32_t prec, size_t tile_ld, uint32_t mask)
 Load a 2D tile of a 2D array using multicast.
 
snrt_dma_txid_t snrt_dma_load_2d_tile_mcast (void *dst, void *src, size_t tile_x1_idx, size_t tile_x0_idx, size_t tile_x1_size, size_t tile_x0_size, size_t full_x0_size, uint32_t prec, uint32_t mask)
 Load a 2D tile of a 2D array.
 
snrt_dma_txid_t snrt_dma_load_2d_tile_mcast (void *dst, void *src, size_t tile_x1_idx, size_t tile_x0_idx, size_t tile_x1_size, size_t tile_x0_size, size_t full_x0_size, uint32_t prec, snrt_comm_t comm)
 Load a 2D tile of a 2D array using multicast.
 
snrt_dma_txid_t snrt_dma_load_2d_tile_in_banks (void *dst, void *src, size_t tile_x1_idx, size_t tile_x0_idx, size_t tile_x1_size, size_t tile_x0_size, size_t full_x0_size, uint32_t prec, size_t num_banks)
 Load a 2D tile of a 2D array and reshape it to occupy a subset of TCDM banks.
 
snrt_dma_txid_t snrt_dma_store_2d_tile (void *dst, void *src, size_t tile_x1_idx, size_t tile_x0_idx, size_t tile_x1_size, size_t tile_x0_size, size_t full_x0_size, uint32_t prec, size_t tile_ld)
 Store a 2D tile to a 2D array.
 
snrt_dma_txid_t snrt_dma_store_2d_tile (void *dst, void *src, size_t tile_x1_idx, size_t tile_x0_idx, size_t tile_x1_size, size_t tile_x0_size, size_t full_x0_size, uint32_t prec)
 Store a 2D tile of a 2D array.
 
snrt_dma_txid_t snrt_dma_store_2d_tile_from_banks (void *dst, void *src, size_t tile_x1_idx, size_t tile_x0_idx, size_t tile_x1_size, size_t tile_x0_size, size_t full_x0_size, uint32_t prec, size_t num_banks)
 Store a 2D tile of a 2D array from a 1D layout occupying a subset of TCDM banks.
 

Detailed Description

This file provides functions to program the Snitch DMA.

Function Documentation

◆ snrt_dma_1d_to_2d()

snrt_dma_txid_t snrt_dma_1d_to_2d ( volatile void * dst,
volatile void * src,
size_t size,
size_t row_size,
size_t stride )
inline

Transfer and reshape a 1D array into a 2D array.

Parameters
dstPointer to the destination array.
srcPointer to the source array.
sizeNumber of bytes to transfer.
row_sizeSize of a row in the 2D array, in bytes.
strideStride between successive rows in the 2D array, in bytes.
529 {
530 return snrt_dma_start_2d(dst, src, row_size, stride, row_size,
531 size / row_size);
532}
snrt_dma_txid_t snrt_dma_start_2d(uint64_t dst, uint64_t src, size_t size, size_t dst_stride, size_t src_stride, size_t repeat, uint32_t channel)
Start an asynchronous 2D DMA transfer with 64-bit wide pointers.
Definition dma.h:233

◆ snrt_dma_2d_to_1d()

snrt_dma_txid_t snrt_dma_2d_to_1d ( volatile void * dst,
volatile void * src,
size_t size,
size_t row_size,
size_t stride )
inline

Transfer and reshape a 2D array into a 1D array.

Parameters
dstPointer to the destination array.
srcPointer to the source array.
sizeNumber of bytes to transfer.
row_sizeSize of a row in the 2D array, in bytes.
strideStride between successive rows in the 2D array, in bytes.
544 {
545 return snrt_dma_start_2d(dst, src, row_size, row_size, stride,
546 size / row_size);
547}

◆ snrt_dma_busy()

static uint32_t snrt_dma_busy ( const uint32_t channel)
inlinestatic

Read DMA busy flag.

Parameters
channelThe index of the channel.
Note
The function passes the channel argument as an immediate, thus this must be known at compile time. As a consequence, the function must use internal linkage (static keyword) and must be always inlined. This is true also for all functions invoking this function, and passing down an argument to channel.
325 {
326#ifdef SNRT_SUPPORTS_DMA
327 uint32_t busy;
328 asm volatile("dmstati %[busy], (%[channel] << 2) | 2 \n"
329 : [ busy ] "=r"(busy)
330 : [ channel ] "i"(channel)
331 :);
332 return busy;
333#else
334 return 0;
335#endif
336}

◆ snrt_dma_disable_multicast()

void snrt_dma_disable_multicast ( )
inline

Disable multicast for successive transfers.

Successive DMA transfers will be unicast transfers

void snrt_dma_set_awuser(uint64_t field)
Set AW user field of the DMA's AXI interface.
Definition dma.h:70

◆ snrt_dma_disable_reduction()

void snrt_dma_disable_reduction ( )
inline

Disable reduction operations for successive transfers.

Successive DMA transfers will be unicast transfers

◆ snrt_dma_enable_multicast()

void snrt_dma_enable_multicast ( uint64_t mask)
inline

Enable multicast for successive transfers.

All transfers performed after this call will be multicast to all addresses specified by the address and mask pair.

Parameters
maskMulticast mask value
87 {
89 op.f.opcode = SNRT_COLLECTIVE_MULTICAST;
90 op.f.mask = mask;
92}
Definition sync_decls.h:40

◆ snrt_dma_enable_reduction()

void snrt_dma_enable_reduction ( uint64_t mask,
snrt_collective_opcode_t opcode )
inline

Enable reduction operations for successive transfers.

All transfers performed after this call will be part of a reduction involving all masters identified by the mask.

Parameters
maskMask defines all involved members
opcodeType of reduction operation
103 {
105 op.f.opcode = opcode;
106 op.f.mask = mask;
108}

◆ snrt_dma_load_1d_tile()

snrt_dma_txid_t snrt_dma_load_1d_tile ( volatile void * dst,
volatile void * src,
size_t tile_idx,
size_t tile_size,
uint32_t prec )
inline

Load a tile of a 1D array.

Parameters
dstPointer to the tile destination.
srcPointer to the source array.
tile_idxIndex of the tile in the 1D array.
tile_sizeNumber of elements within a tile of the 1D array.
precNumber of bytes of each element in the 1D array.
474 {
475 size_t tile_nbytes = tile_size * prec;
476 return snrt_dma_start_1d(
477 (uint64_t)dst, (uint64_t)src + tile_idx * tile_nbytes, tile_nbytes);
478}
uint32_t snrt_dma_start_1d(uint64_t dst, uint64_t src, size_t size, uint32_t channel)
Start an asynchronous 1D DMA transfer with 64-bit wide pointers on a specific DMA channel.
Definition dma.h:27

◆ snrt_dma_load_1d_tile_mcast()

snrt_dma_txid_t snrt_dma_load_1d_tile_mcast ( void * dst,
void * src,
size_t tile_idx,
size_t tile_size,
uint32_t prec,
uint64_t mask )
inline

Load a tile of a 1D array.

Parameters
dstPointer to the tile destination.
srcPointer to the source array.
tile_idxIndex of the tile in the 1D array.
tile_sizeNumber of elements within a tile of the 1D array.
precNumber of bytes of each element in the 1D array.
maskMulticast mask applied on the destination address.
493 {
494 size_t tile_nbytes = tile_size * prec;
495 return snrt_dma_start_1d_mcast((uintptr_t)dst,
496 (uintptr_t)src + tile_idx * tile_nbytes,
497 tile_nbytes, mask);
498}
uint32_t snrt_dma_start_1d_mcast(uint64_t dst, uint64_t src, size_t size, uint64_t mask, uint32_t channel=0)
Start an asynchronous multicast 1D DMA transfer with 64-bit wide pointers.
Definition dma.h:165

◆ snrt_dma_load_2d_tile() [1/2]

snrt_dma_txid_t snrt_dma_load_2d_tile ( void * dst,
void * src,
size_t tile_x1_idx,
size_t tile_x0_idx,
size_t tile_x1_size,
size_t tile_x0_size,
size_t full_x0_size,
uint32_t prec )
inline

Load a 2D tile of a 2D array.

The stride in the destination tile is assumed to be that of a 1D tile, effectively. In other words, this is the same as snrt_dma_2d_to_1d().

See also
snrt_dma_load_2d_tile(void *, void *, size_t, size_t, size_t, size_t, size_t, uint32_t, size_t) for a detailed description of the parameters.
611 {
612 return snrt_dma_load_2d_tile(dst, src, tile_x1_idx, tile_x0_idx,
613 tile_x1_size, tile_x0_size, full_x0_size, prec,
614 tile_x0_size * prec);
615}
snrt_dma_txid_t snrt_dma_load_2d_tile(void *dst, void *src, size_t tile_x1_idx, size_t tile_x0_idx, size_t tile_x1_size, size_t tile_x0_size, size_t full_x0_size, uint32_t prec, size_t tile_ld)
Load a 2D tile of a 2D array.
Definition dma.h:580

◆ snrt_dma_load_2d_tile() [2/2]

snrt_dma_txid_t snrt_dma_load_2d_tile ( void * dst,
void * src,
size_t tile_x1_idx,
size_t tile_x0_idx,
size_t tile_x1_size,
size_t tile_x0_size,
size_t full_x0_size,
uint32_t prec,
size_t tile_ld )
inline

Load a 2D tile of a 2D array.

Parameters
dstPointer to the tile destination.
srcPointer to the source array.
tile_x1_idxOutermost coordinate of the tile in the 2D array.
tile_x0_idxInnermost coordinate of the tile in the 2D array.
tile_x1_sizeNumber of elements in the outermost dimension of the tile.
tile_x0_sizeNumber of elements in the innermost dimension of the tile.
full_x0_sizeNumber of elements in the innermost dimension of the array.
precNumber of bytes of each element in the 2D array.
tile_ldLeading dimension of the tile, in bytes.
583 {
584 size_t src_offset = 0;
585 // Advance src array in x0 and x1 dimensions, and convert to byte offset
586 src_offset += tile_x0_idx * tile_x0_size;
587 src_offset += tile_x1_idx * tile_x1_size * full_x0_size;
588 src_offset *= prec;
589 // Initiate transfer
590 return snrt_dma_start_2d((uint64_t)dst, // dst
591 (uint64_t)src + src_offset, // src
592 tile_x0_size * prec, // size
593 tile_ld, // dst_stride
594 full_x0_size * prec, // src_stride
595 tile_x1_size // repeat
596 );
597}

◆ snrt_dma_load_2d_tile_in_banks()

snrt_dma_txid_t snrt_dma_load_2d_tile_in_banks ( void * dst,
void * src,
size_t tile_x1_idx,
size_t tile_x0_idx,
size_t tile_x1_size,
size_t tile_x0_size,
size_t full_x0_size,
uint32_t prec,
size_t num_banks )
inline

Load a 2D tile of a 2D array and reshape it to occupy a subset of TCDM banks.

Parameters
dstPointer to the tile destination.
srcPointer to the source array.
tile_x1_idxOutermost coordinate of the tile in the 2D array.
tile_x0_idxInnermost coordinate of the tile in the 2D array.
tile_x1_sizeNumber of elements in the outermost dimension of the tile.
tile_x0_sizeNumber of elements in the innermost dimension of the tile.
full_x0_sizeNumber of elements in the innermost dimension of the array.
precNumber of bytes of each element in the 2D array.
num_banksNumber of banks to reshape the tile into.
701 {
702 // Calculate new tile size after reshaping the tile in the selected banks
703 size_t tile_x0_size_in_banks = (num_banks * SNRT_TCDM_BANK_WIDTH) / prec;
704 size_t tile_x1_size_in_banks =
705 ceil((tile_x1_size * tile_x0_size) / (double)tile_x0_size_in_banks);
706 size_t tile_ld = SNRT_TCDM_HYPERBANK_WIDTH;
707 return snrt_dma_load_2d_tile(dst, src, tile_x1_idx, tile_x0_idx,
708 tile_x1_size_in_banks, tile_x0_size_in_banks,
709 full_x0_size, prec, tile_ld);
710}

◆ snrt_dma_load_2d_tile_mcast() [1/3]

snrt_dma_txid_t snrt_dma_load_2d_tile_mcast ( void * dst,
void * src,
size_t tile_x1_idx,
size_t tile_x0_idx,
size_t tile_x1_size,
size_t tile_x0_size,
size_t full_x0_size,
uint32_t prec,
size_t tile_ld,
uint32_t mask )
inline

Load a 2D tile of a 2D array using multicast.

Parameters
maskMulticast mask.
See also
snrt_dma_load_2d_tile(void *, void *, size_t, size_t, size_t, size_t, size_t, uint32_t, size_t) for a description of the other parameters.
627 {
628 size_t src_offset = 0;
629 // Advance src array in x0 and x1 dimensions, and convert to byte offset
630 src_offset += tile_x0_idx * tile_x0_size;
631 src_offset += tile_x1_idx * tile_x1_size * full_x0_size;
632 src_offset *= prec;
633 // Initiate transfer
634 return snrt_dma_start_2d_mcast((uint64_t)dst, // dst
635 (uint64_t)src + src_offset, // src
636 tile_x0_size * prec, // size
637 tile_ld, // dst_stride
638 full_x0_size * prec, // src_stride
639 tile_x1_size, // repeat
640 mask // mask
641 );
642}
uint32_t snrt_dma_start_2d_mcast(uint64_t dst, uint64_t src, size_t size, size_t dst_stride, size_t src_stride, size_t repeat, uint32_t mask, uint32_t channel=0)
Start an asynchronous, multicast 2D DMA transfer with 64-bit wide pointers.
Definition dma.h:288

◆ snrt_dma_load_2d_tile_mcast() [2/3]

snrt_dma_txid_t snrt_dma_load_2d_tile_mcast ( void * dst,
void * src,
size_t tile_x1_idx,
size_t tile_x0_idx,
size_t tile_x1_size,
size_t tile_x0_size,
size_t full_x0_size,
uint32_t prec,
snrt_comm_t comm )
inline

Load a 2D tile of a 2D array using multicast.

Parameters
commCommunicator specifying which clusters to multicast to.

The stride in the destination tile is assumed to be that of a 1D tile, effectively. In other words, this is similar to snrt_dma_2d_to_1d().

See also
snrt_dma_load_2d_tile_mcast(void *, void *, size_t, size_t, size_t, size_t, size_t, uint32_t, size_t, uint32_t) for a detailed description of the parameters.
675 {
676 uint64_t mask = snrt_get_collective_mask(comm);
677 return snrt_dma_load_2d_tile_mcast(dst, src, tile_x1_idx, tile_x0_idx,
678 tile_x1_size, tile_x0_size, full_x0_size,
679 prec, mask);
680}
snrt_dma_txid_t snrt_dma_load_2d_tile_mcast(void *dst, void *src, size_t tile_x1_idx, size_t tile_x0_idx, size_t tile_x1_size, size_t tile_x0_size, size_t full_x0_size, uint32_t prec, size_t tile_ld, uint32_t mask)
Load a 2D tile of a 2D array using multicast.
Definition dma.h:624

◆ snrt_dma_load_2d_tile_mcast() [3/3]

snrt_dma_txid_t snrt_dma_load_2d_tile_mcast ( void * dst,
void * src,
size_t tile_x1_idx,
size_t tile_x0_idx,
size_t tile_x1_size,
size_t tile_x0_size,
size_t full_x0_size,
uint32_t prec,
uint32_t mask )
inline

Load a 2D tile of a 2D array.

The stride in the destination tile is assumed to be that of a 1D tile, effectively. In other words, this is similar to snrt_dma_2d_to_1d().

See also
snrt_dma_load_2d_tile_mcast(void *, void *, size_t, size_t, size_t, size_t, size_t, uint32_t, size_t, uint32_t) for a detailed description of the parameters.
656 {
657 return snrt_dma_load_2d_tile_mcast(dst, src, tile_x1_idx, tile_x0_idx,
658 tile_x1_size, tile_x0_size, full_x0_size,
659 prec, tile_x0_size * prec, mask);
660}

◆ snrt_dma_memset()

void snrt_dma_memset ( void * ptr,
uint8_t value,
uint32_t len )
inline

Fast memset function performed by DMA.

Parameters
ptrPointer to the start of the region.
valueValue to set.
lenNumber of bytes, must be a multiple of the DMA bus width to use the DMA.
440 {
441#ifdef SNRT_SUPPORTS_DMA
442 // We set the first 64 bytes to the value, and then we use the DMA to copy
443 // these into the remaining memory region. DMA is used only if len is
444 // larger than 64 bytes, and an integer multiple of 64 bytes.
445 size_t n_1d_transfers = len / 64;
446 size_t use_dma = (len % 64) == 0 && len > 64;
447 uint8_t *p = (uint8_t *)ptr;
448
449 uint32_t nbytes = len < 64 || !use_dma ? len : 64;
450 while (nbytes--) {
451 *p++ = value;
452 }
453
454 if (use_dma) {
455 snrt_dma_start_2d(ptr, ptr, 64, 64, 0, n_1d_transfers);
457 }
458#else
459 memset(ptr, (int)value, len);
460#endif
461}
static void snrt_dma_wait_all(const uint32_t channel=0)
Block until a specific DMA channel is idle.
Definition dma.h:392

◆ snrt_dma_reduction_load_1d_tile()

snrt_dma_txid_t snrt_dma_reduction_load_1d_tile ( void * dst,
void * src,
size_t tile_idx,
size_t tile_size,
uint32_t prec,
uint64_t mask,
snrt_collective_opcode_t opcode )
inline

Load a tile of a 1D array.

Parameters
dstPointer to the tile destination.
srcPointer to the source array.
tile_idxIndex of the tile in the 1D array.
tile_sizeNumber of elements within a tile of the 1D array.
precNumber of bytes of each element in the 1D array.
maskMask for reduction operation.
opcodeReduction operation.
512 {
513 size_t tile_nbytes = tile_size * prec;
514 return snrt_dma_start_1d_reduction((uintptr_t)dst,
515 (uintptr_t)src + tile_idx * tile_nbytes,
516 tile_nbytes, mask, opcode);
517}
uint32_t snrt_dma_start_1d_reduction(uint64_t dst, uint64_t src, size_t size, uint64_t mask, snrt_collective_opcode_t opcode, uint32_t channel=0)
Start an asynchronous reduction 1D DMA transfer with 64-bit wide pointers.
Definition dma.h:130

◆ snrt_dma_set_awuser()

void snrt_dma_set_awuser ( uint64_t field)
inline

Set AW user field of the DMA's AXI interface.

All DMA transfers performed after this call are equipped with the given AW user field

Parameters
fieldDefines the AW user field for the AXI transfer
70 {
71#ifdef SNRT_SUPPORTS_DMA
72 uint32_t user_low = (uint32_t)(field);
73 uint32_t user_high = (uint32_t)(field >> 32);
74 asm volatile("dmuser %[user_low], %[user_high] \n"
75 :
76 : [ user_low ] "r"(user_low), [ user_high ] "r"(user_high));
77#endif
78}

◆ snrt_dma_start_1d() [1/2]

uint32_t snrt_dma_start_1d ( uint64_t dst,
uint64_t src,
size_t size,
uint32_t channel )
inline

Start an asynchronous 1D DMA transfer with 64-bit wide pointers on a specific DMA channel.

Parameters
dstThe destination address.
srcThe source address.
sizeThe size of the transfer in bytes.
channelThe index of the channel.
Returns
The DMA transfer ID.
28 {
29#ifdef SNRT_SUPPORTS_DMA
30 uint32_t dst_lo = dst & 0xFFFFFFFF;
31 uint32_t dst_hi = dst >> 32;
32 uint32_t src_lo = src & 0xFFFFFFFF;
33 uint32_t src_hi = src >> 32;
34 uint32_t cfg = (channel << 2) | 0b00;
35 uint32_t txid;
36
37 asm volatile(
38 "dmsrc %[src_lo], %[src_hi] \n"
39 "dmdst %[dst_lo], %[dst_hi] \n"
40 "dmcpy %[txid], %[size], %[cfg] \n"
41 : [ txid ] "=r"(txid)
42 : [ src_lo ] "r"(src_lo), [ src_hi ] "r"(src_hi),
43 [ dst_lo ] "r"(dst_lo), [ dst_hi ] "r"(dst_hi), [ size ] "r"(size),
44 [ cfg ] "r"(cfg));
45 return txid;
46#else
47 memcpy((void *)dst, (const void *)src, size);
48 return 0;
49#endif
50}

◆ snrt_dma_start_1d() [2/2]

uint32_t snrt_dma_start_1d ( volatile void * dst,
volatile void * src,
size_t size,
uint32_t channel = 0 )
inline

Start an asynchronous 1D DMA transfer using native-size pointers.

This is a convenience overload of snrt_dma_start_1d(uint64_t, uint64_t, size_t, uint32_t) using void* pointers.

59 {
60 return snrt_dma_start_1d((uint64_t)dst, (uint64_t)src, size, channel);
61}

◆ snrt_dma_start_1d_mcast() [1/3]

uint32_t snrt_dma_start_1d_mcast ( uint64_t dst,
uint64_t src,
size_t size,
snrt_comm_t comm,
uint32_t channel = 0 )
inline

Start an asynchronous multicast 1D DMA transfer with 64-bit wide pointers.

Parameters
commThe communicator for the multicast operation
See also
snrt_dma_start_1d(uint64_t, uint64_t, size_t, uint32_t) for a description of the other parameters.
182 {
183 uint64_t mask = snrt_get_collective_mask(comm);
184 uint32_t txid = snrt_dma_start_1d_mcast(dst, src, size, mask, channel);
185 return txid;
186}

◆ snrt_dma_start_1d_mcast() [2/3]

uint32_t snrt_dma_start_1d_mcast ( uint64_t dst,
uint64_t src,
size_t size,
uint64_t mask,
uint32_t channel = 0 )
inline

Start an asynchronous multicast 1D DMA transfer with 64-bit wide pointers.

Parameters
maskThe mask for the multicast operation
See also
snrt_dma_start_1d(uint64_t, uint64_t, size_t, uint32_t) for a description of the other parameters.
166 {
168 uint32_t txid = snrt_dma_start_1d(dst, src, size, channel);
170 return txid;
171}
void snrt_dma_disable_multicast()
Disable multicast for successive transfers.
Definition dma.h:114
void snrt_dma_enable_multicast(uint64_t mask)
Enable multicast for successive transfers.
Definition dma.h:87

◆ snrt_dma_start_1d_mcast() [3/3]

uint32_t snrt_dma_start_1d_mcast ( volatile void * dst,
volatile void * src,
size_t size,
uint64_t mask,
uint32_t channel = 0 )
inline

Start an asynchronous multicast 1D DMA transfer using native-size pointers.

This is a convenience overload of snrt_dma_start_1d_mcast(uint64_t, uint64_t, size_t, uint64_t, uint32_t) using void* pointers.

215 {
216 return snrt_dma_start_1d_mcast((uint64_t)dst, (uint64_t)src, size, mask,
217 channel);
218}

◆ snrt_dma_start_1d_reduction() [1/3]

uint32_t snrt_dma_start_1d_reduction ( uint64_t dst,
uint64_t src,
size_t size,
snrt_comm_t comm,
snrt_collective_opcode_t opcode,
uint32_t channel = 0 )
inline

Start an asynchronous reduction 1D DMA transfer with 64-bit wide pointers.

Parameters
commThe communicator for the reduction operation
opcodeReduction operation
See also
snrt_dma_start_1d(uint64_t, uint64_t, size_t, uint32_t) for a description of the other parameters.
151 {
152 uint64_t mask = snrt_get_collective_mask(comm);
153 uint32_t txid =
154 snrt_dma_start_1d_reduction(dst, src, size, mask, opcode, channel);
155 return txid;
156}

◆ snrt_dma_start_1d_reduction() [2/3]

uint32_t snrt_dma_start_1d_reduction ( uint64_t dst,
uint64_t src,
size_t size,
uint64_t mask,
snrt_collective_opcode_t opcode,
uint32_t channel = 0 )
inline

Start an asynchronous reduction 1D DMA transfer with 64-bit wide pointers.

Parameters
maskMask defines all involved members
opcodeReduction operation
See also
snrt_dma_start_1d(uint64_t, uint64_t, size_t, uint32_t) for a description of the other parameters.
133 {
134 snrt_dma_enable_reduction(mask, opcode);
135 uint32_t txid = snrt_dma_start_1d(dst, src, size, channel);
137 return txid;
138}
void snrt_dma_disable_reduction()
Disable reduction operations for successive transfers.
Definition dma.h:120
void snrt_dma_enable_reduction(uint64_t mask, snrt_collective_opcode_t opcode)
Enable reduction operations for successive transfers.
Definition dma.h:102

◆ snrt_dma_start_1d_reduction() [3/3]

uint32_t snrt_dma_start_1d_reduction ( volatile void * dst,
volatile void * src,
size_t size,
uint64_t mask,
snrt_collective_opcode_t opcode,
uint32_t channel = 0 )
inline

Start an asynchronous reduction 1D DMA transfer using native-size pointers.

This is a convenience overload of snrt_dma_start_1d_reduction(uint64_t, uint64_t, size_t, uint64_t, uint32_t, uint32_t) using void* pointers.

200 {
201 return snrt_dma_start_1d_reduction((uint64_t)dst, (uint64_t)src, size, mask,
202 opcode, channel);
203}

◆ snrt_dma_start_2d() [1/2]

snrt_dma_txid_t snrt_dma_start_2d ( uint64_t dst,
uint64_t src,
size_t size,
size_t dst_stride,
size_t src_stride,
size_t repeat,
uint32_t channel )
inline

Start an asynchronous 2D DMA transfer with 64-bit wide pointers.

Parameters
dstThe destination address.
srcThe source address.
sizeThe size of every 1D transfer within the 2D transfer in bytes.
dst_strideThe offset between consecutive 1D transfers at the destination, in bytes.
src_strideThe offset between consecutive 1D transfers at the source, in bytes.
repeatThe number of 1D transfers composing the 2D transfer.
channelThe index of the channel.
Returns
The DMA transfer ID.
236 {
237#ifdef SNRT_SUPPORTS_DMA
238 uint32_t dst_lo = dst & 0xFFFFFFFF;
239 uint32_t dst_hi = dst >> 32;
240 uint32_t src_lo = src & 0xFFFFFFFF;
241 uint32_t src_hi = src >> 32;
242 uint32_t cfg = (channel << 2) | 0b10;
243 uint32_t txid;
244
245 asm volatile(
246 "dmsrc %[src_lo], %[src_hi] \n"
247 "dmdst %[dst_lo], %[dst_hi] \n"
248 "dmstr %[src_stride], %[dst_stride] \n"
249 "dmrep %[repeat] \n"
250 "dmcpy %[txid], %[size], %[cfg] \n"
251 : [ txid ] "=r"(txid)
252 : [ src_lo ] "r"(src_lo), [ src_hi ] "r"(src_hi),
253 [ dst_lo ] "r"(dst_lo), [ dst_hi ] "r"(dst_hi),
254 [ dst_stride ] "r"(dst_stride), [ src_stride ] "r"(src_stride),
255 [ repeat ] "r"(repeat), [ size ] "r"(size), [ cfg ] "r"(cfg));
256
257 return txid;
258#else
259 // TODO(colluca): we can implement this as a series of memcpy calls
260 return 0;
261#endif
262}

◆ snrt_dma_start_2d() [2/2]

uint32_t snrt_dma_start_2d ( volatile void * dst,
volatile void * src,
size_t size,
size_t dst_stride,
size_t src_stride,
size_t repeat,
uint32_t channel = 0 )
inline

Start an asynchronous 2D DMA transfer using native-size pointers.

This is a convenience overload of snrt_dma_start_2d(uint64_t, uint64_t, size_t, size_t, size_t, size_t, uint32_t) using void* pointers.

274 {
275 return snrt_dma_start_2d((uint64_t)dst, (uint64_t)src, size, dst_stride,
276 src_stride, repeat, channel);
277}

◆ snrt_dma_start_2d_mcast() [1/2]

uint32_t snrt_dma_start_2d_mcast ( uint64_t dst,
uint64_t src,
size_t size,
size_t dst_stride,
size_t src_stride,
size_t repeat,
uint32_t mask,
uint32_t channel = 0 )
inline

Start an asynchronous, multicast 2D DMA transfer with 64-bit wide pointers.

Parameters
maskMulticast mask.
See also
snrt_dma_start_2d(uint64_t, uint64_t, size_t, size_t, size_t, size_t, uint32_t) for a description of the other parameters.
291 {
293 uint32_t txid = snrt_dma_start_2d(dst, src, size, dst_stride, src_stride,
294 repeat, channel);
296 return txid;
297}

◆ snrt_dma_start_2d_mcast() [2/2]

uint32_t snrt_dma_start_2d_mcast ( volatile void * dst,
volatile void * src,
size_t size,
size_t dst_stride,
size_t src_stride,
size_t repeat,
uint32_t mask,
uint32_t channel = 0 )
inline

Start an asynchronous, multicast 2D DMA transfer using native-size pointers.

This is a convenience overload of snrt_dma_start_2d_mcast(uint64_t, uint64_t, size_t, size_t, size_t, size_t, uint32_t, uint32_t) using void* pointers.

310 {
311 return snrt_dma_start_2d_mcast((uint64_t)dst, (uint64_t)src, size,
312 dst_stride, src_stride, repeat, mask,
313 channel);
314}

◆ snrt_dma_start_tracking()

void snrt_dma_start_tracking ( )
inline

Start tracking of dma performance region. Does not have any implications on the HW. Only injects a marker in the DMA traces that can be analyzed.

Deprecated
415 {
416#ifdef SNRT_SUPPORTS_DMA
417 asm volatile("dmstati zero, 0 \n");
418#endif
419}

◆ snrt_dma_stop_tracking()

void snrt_dma_stop_tracking ( )
inline

Stop tracking of dma performance region. Does not have any implications on the HW. Only injects a marker in the DMA traces that can be analyzed.

Deprecated
427 {
428#ifdef SNRT_SUPPORTS_DMA
429 asm volatile("dmstati zero, 0 \n");
430#endif
431}

◆ snrt_dma_store_1d_tile()

snrt_dma_txid_t snrt_dma_store_1d_tile ( void * dst,
void * src,
size_t tile_idx,
size_t tile_size,
uint32_t prec )
inline

Store a tile to a 1D array.

Parameters
dstPointer to the destination array.
srcPointer to the source tile.
tile_idxIndex of the tile in the 1D array.
tile_sizeNumber of elements within a tile of the 1D array.
precNumber of bytes of each element in the 1D array.
559 {
560 size_t tile_nbytes = tile_size * prec;
561 return snrt_dma_start_1d((uint64_t)dst + tile_idx * tile_nbytes,
562 (uint64_t)src, tile_nbytes);
563}

◆ snrt_dma_store_2d_tile() [1/2]

snrt_dma_txid_t snrt_dma_store_2d_tile ( void * dst,
void * src,
size_t tile_x1_idx,
size_t tile_x0_idx,
size_t tile_x1_size,
size_t tile_x0_size,
size_t full_x0_size,
uint32_t prec )
inline

Store a 2D tile of a 2D array.

The stride in the source tile is assumed to be that of a 1D tile, effectively. In other words, this is the same as snrt_dma_1d_to_2d().

See also
snrt_dma_store_2d_tile(void *, void *, size_t, size_t, size_t, size_t, size_t, uint32_t, size_t) for a detailed description of the parameters.
758 {
759 return snrt_dma_store_2d_tile(dst, src, tile_x1_idx, tile_x0_idx,
760 tile_x1_size, tile_x0_size, full_x0_size,
761 prec, tile_x0_size * prec);
762}
snrt_dma_txid_t snrt_dma_store_2d_tile(void *dst, void *src, size_t tile_x1_idx, size_t tile_x0_idx, size_t tile_x1_size, size_t tile_x0_size, size_t full_x0_size, uint32_t prec, size_t tile_ld)
Store a 2D tile to a 2D array.
Definition dma.h:727

◆ snrt_dma_store_2d_tile() [2/2]

snrt_dma_txid_t snrt_dma_store_2d_tile ( void * dst,
void * src,
size_t tile_x1_idx,
size_t tile_x0_idx,
size_t tile_x1_size,
size_t tile_x0_size,
size_t full_x0_size,
uint32_t prec,
size_t tile_ld )
inline

Store a 2D tile to a 2D array.

Parameters
dstPointer to the destination array.
srcPointer to the source tile.
tile_x1_idxOutermost coordinate of the tile in the 2D array.
tile_x0_idxInnermost coordinate of the tile in the 2D array.
tile_x1_sizeNumber of elements in the outermost dimension of the tile.
tile_x0_sizeNumber of elements in the innermost dimension of the tile.
full_x0_sizeNumber of elements in the innermost dimension of the array.
precNumber of bytes of each element in the 2D array.
tile_ldLeading dimension of the tile, in bytes.
730 {
731 size_t dst_offset = 0;
732 // Advance dst array in x0 and x1 dimensions, and convert to byte offset
733 dst_offset += tile_x0_idx * tile_x0_size;
734 dst_offset += tile_x1_idx * tile_x1_size * full_x0_size;
735 dst_offset *= prec;
736 // Initiate transfer
737 return snrt_dma_start_2d((uint64_t)dst + dst_offset, // dst
738 (uint64_t)src, // src
739 tile_x0_size * prec, // size
740 full_x0_size * prec, // dst_stride
741 tile_ld, // src_stride
742 tile_x1_size // repeat
743 );
744}

◆ snrt_dma_store_2d_tile_from_banks()

snrt_dma_txid_t snrt_dma_store_2d_tile_from_banks ( void * dst,
void * src,
size_t tile_x1_idx,
size_t tile_x0_idx,
size_t tile_x1_size,
size_t tile_x0_size,
size_t full_x0_size,
uint32_t prec,
size_t num_banks )
inline

Store a 2D tile of a 2D array from a 1D layout occupying a subset of TCDM banks.

Parameters
dstPointer to the destination array.
srcPointer to the source tile.
tile_x1_idxOutermost coordinate of the tile in the 2D array.
tile_x0_idxInnermost coordinate of the tile in the 2D array.
tile_x1_sizeNumber of elements in the outermost dimension of the tile.
tile_x0_sizeNumber of elements in the innermost dimension of the tile.
full_x0_sizeNumber of elements in the innermost dimension of the array.
precNumber of bytes of each element in the 2D array.
num_banksNumber of banks the tile is stored in.
783 {
784 // Calculate new tile size after reshaping the tile in the selected banks
785 size_t tile_x0_size_in_banks = (num_banks * SNRT_TCDM_BANK_WIDTH) / prec;
786 size_t tile_x1_size_in_banks =
787 ceil((tile_x1_size * tile_x0_size) / (double)tile_x0_size_in_banks);
788 size_t tile_ld = SNRT_TCDM_HYPERBANK_WIDTH;
789 return snrt_dma_store_2d_tile(dst, src, tile_x1_idx, tile_x0_idx,
790 tile_x1_size_in_banks, tile_x0_size_in_banks,
791 full_x0_size, prec, tile_ld);
792}

◆ snrt_dma_wait()

static void snrt_dma_wait ( snrt_dma_txid_t txid,
const uint32_t channel = 0 )
inlinestatic

Block until a DMA transfer finishes on a specific DMA channel.

Parameters
txidThe DMA transfer's ID.
channelThe index of the channel.
Note
The function passes the channel argument as an immediate, thus this must be known at compile time. As a consequence, the function must use internal linkage (static keyword) and must be always inlined. This is true also for all functions invoking this function, and passing down an argument to channel.
371 {
372#ifdef SNRT_SUPPORTS_DMA
373 asm volatile(
374 "1: \n"
375 "dmstati t0, (%[channel] << 2) | 0 \n"
376 "bltu t0, %[txid], 1b \n"
377 :
378 : [ txid ] "r"(txid), [ channel ] "i"(channel)
379 : "t0");
380#endif
381}

◆ snrt_dma_wait_all()

static void snrt_dma_wait_all ( const uint32_t channel = 0)
inlinestatic

Block until a specific DMA channel is idle.

Parameters
channelThe index of the channel.
Note
The function passes the channel argument as an immediate, thus this must be known at compile time. As a consequence, the function must use internal linkage (static keyword) and must be always inlined. This is true also for all functions invoking this function, and passing down an argument to channel.
392 {
393#ifdef SNRT_SUPPORTS_DMA
394 while (snrt_dma_busy(channel))
395 ;
396#endif
397}
static uint32_t snrt_dma_busy(const uint32_t channel)
Read DMA busy flag.
Definition dma.h:325

◆ snrt_dma_wait_all_channels()

void snrt_dma_wait_all_channels ( uint32_t num_channels)
inline

Block until the first num_channels channels are idle.

Parameters
num_channelsThe number of channels to wait on.
403 {
404 for (int c = 0; c < num_channels; c++) {
406 }
407}

◆ snrt_dma_would_block()

static uint32_t snrt_dma_would_block ( const uint32_t channel)
inlinestatic

Read DMA would_block flag.

Parameters
channelThe index of the channel.
Note
The function passes the channel argument as an immediate, thus this must be known at compile time. As a consequence, the function must use internal linkage (static keyword) and must be always inlined. This is true also for all functions invoking this function, and passing down an argument to channel.
347 {
348#ifdef SNRT_SUPPORTS_DMA
349 uint32_t would_block;
350 asm volatile("dmstati %[would_block], (%[channel] << 2) | 3 \n"
351 : [ would_block ] "=r"(would_block)
352 : [ channel ] "i"(channel)
353 :);
354 return would_block;
355#else
356 return 0;
357#endif
358}