Framework Components FAQ

From Texas Instruments Wiki
Jump to: navigation, search

What is Framework Components?

Framework Components is comprised of XDAIS algorithm resource managers and functional interfaces.

  • DSKT2 - used for creating and interacting with XDAIS algorithms.
  • RMAN - General purpose resource manager (introduced in FC 2.00)
  • ECPY - DMA-based memory copy functional library built to work with the RMAN resource manager
  • DMAN3 - used for sharing QDMA channels from an EDMA3 device with XDAIS algorithms. (Deprecated as of FC 3.23)
  • ACPY3 - DMA-based memory copy functional library. (Deprecated as of FC 3.23)

The FC API Reference Guide provides details on the APIs.

TI's marketing team also has a description of the Framework Components product.

Where can I download Framework Components?

Download Framework Components here

DSKT2 Questions

Where's the DSKT2 User's Guide?

DSKT2 User's Guide is here.

The FC 2.x API Reference Guide also includes DSKT2 API documentation.

What exactly is "scratch memory" and when can my algorithm use it ?

Scratch memory is a scheme for sharing memory between XDAIS algorithms. DSKT2 implements this scheme by distributing available memory (usually internal memory) into scratch groups and allowing algorithms to be associated with a particular scratch group. The distribution of different memory segments within various scratch groups is done via DSKT2's configuration.

All algorithms in a particular scratch group potentially share their scratch memory, hence they do not truly 'own' this memory at the time the algorithm is created or granted its memory (by DSKT2). Only after the algorithm is 'activated' (i.e, the framework calls the IALG_Fxns.algActivate() on the algorithm's IALG_Handle), does it become the sole owner of it's scratch memory. The algorithm continues to own the memory till the point the framework 'deactivates' the algorithm (by calling IALG_Fxns.algDeactivate()).

One of the most common reasons for inconsistent codec behavior when integrating multiple algorithms in a framework, is improperly written algActivate(), algDeactivate() functions. Often algorithm writers make the mistake of clearing out scratch memory as soon as it is assigned (i.e. during IALG_Fxns.algInit()). However, at this time, the algorithm does NOT own the scratch memory (it is the owner of only the persistent memory granted to it); and another algorithm in the system might be using this scratch memory. Algorithms should only access this scratch memory between the algActivate() and algDeactivate() calls by the framework.

Another common mistake is not backing up scratch memory to persistent memory. After an algorithm is deactivated, its scratch memory contents may be overwritten by some other algorithm in the same scratch group. Hence, any memory contents that need to 'persist' have to be copied from the scratch memory to persistent memory in the IALG_Fxns.algDeactivate() function.

Scratch memory concepts are further explained in DSKT2 User's Guide.

Which heap does alg-requested IALG_EXTERNAL memory come from?

The same heap configured for DSKT2.ESDATA.

In general, DSKT2 does its best to follow this mapping:

  • IALG_DARAM0: DSKT2.DARAM0
  • IALG_DARAM1: DSKT2.DARAM1
  • IALG_DARAM2: DSKT2.DARAM2
  • IALG_SARAM0: DSKT2.SARAM0
  • IALG_SARAM1: DSKT2.SARAM1
  • IALG_SARAM2: DSKT2_SARAM2
  • IALG_IPROG: DSKT2.IPROG
  • IALG_EPROG: DSKT2.EPROG
  • IALG_ESDATA: DSKT2.ESDATA
  • All other (including IALG_EXTERNAL): DSKT2.ESDATA

Why doesn't DSKT2_freeAlg() call my alg's algFree() method?

DSKT2 doesn't invoke the alg's algFree() method in today's DSKT2_freealg() implementation because it remembers the resources the alg requested during its algInit(). As a result, it can free the algorithms memory without invoking the algorithm's algFree().

This optimization has a side effect in that it "works around" a common algorithm defect of not returning the same memTab table that was returned during initialization. In order to return the right memTab, the alg often must retain the create params provided to it during init. A common alg defect was to not retain these create params, and as a result, return an incorrect memTab. While this is still a defect, and the alg should be fixed, these defects are not seen when using DSKT2.

Note that this optimization is done in today's DSKT2 implementation, but may not be done in future implementations, and other frameworks that XDAIS algs can plug into may not make this optimization. As a result, algs should not use this internal, DSKT2-specific implementation detail; algs should continue to implement algFree().

What is the lazy deactivation feature?

Per the XDAIS spec, applications must call DSKT2_activateAlg() and DSKT2_deactivateAlg() before and after invoking an algorithm's processing methods.

DSKT2 employs a lazy deactivate feature where calls to DSKT2_deactivateAlg() simply place the algorithm instance on a list of deactivated algs. The deactivated algorithm's IALG_Fxns->algDeactivate() method will not be immediately invoked. The deactivated algorithm's IALG_Fxns->algDeactivate() method is really called when another algorithm instance in the same scratch group is activated.

If no other algorithm instances in the same scratch group is activated before the lazily deactivated instance, the preparatory DSKT2_activateAlg() will simply take the alg off the deactivated list.

This removes any unnecessary, back-to-back, algDeactivate()/algActivate() calls as a performance optimization.

Why does DSKT2 provide external memory when my alg asked for internal?

DSKT2, by default, employs a best effort, "create the alg if at all possible" approach. Per the XDAIS spec, the memory requested by the algorithm is a request, not a requirement. As a result, while DSKT2 will first try to satisfy the exact memory request, if that can't be met, it will try external memory as a backup. The thinking is that while the algorithm may run slower, at least it can be created and run.

Some algorithms require internal memory as they may be using hardware accelerators which can only access internal memory. In these cases, DSKT2's granting of external memory can create issues. To provide system integrators with additional configuration tooling, DSKT2 provides a configuration parameter:

config Bool ALLOW_EXTERNAL_SCRATCH = true;

to enable/disable this best effort approach. The default is set to true. However, configuration scripts can override the default by setting:

DSKT2 = xdc.useModule('ti.sdo.fc.dskt2.DSKT2');
DSKT2.ALLOW_EXTERNAL_SCRATCH = false;

which results in error being returned when there isn't available internal memory.

Additionally, the algorithm's themselves can (and should!) check in their IALG_Fxns.algInit() whether the "assigned" memory is internal or not and fail when the algorithm knows it must have internal memory. This test can be done by checking the assigned IALG_MemAttrs via the IALG supplied macro IALG_isOffChip(s), and returning failure when appropriate.

Unfortunately many algorithms don't perform these checks, as it is not mandated, and the conservative DSKT2.ALLOW_EXTERNAL_SCRATCH configuration approach is an option.

ACPY3 Questions

Why does my alg hang in ACPY3_wait()?

One of most common issues seen when using ACPY3 is a "hang" in the call to ACPY3_wait(). ACPY3_wait() call simply polls on the IPR bit corresponding to the last transfer (in the series of configured linked transfers). A hang here indicates that the actual transfer never went through or completed. The following are a list of common reasons for getting stuck in ACPY3_wait():

  • If you are running on the simulator, you might be hitting a known simulator bug, that causes any transfer with ACNT > 16 to hang. CCS version 3.3.56 has fixed the issue.
  • If running on hardware, the hang most likely occurs when DMAN3's internal memory has not been configured correctly. Make sure DMAN3's configuration parameter DMAN3.heapInternal is actually configured to point to an Internal memory heap. Below are some details on this issue:
    • ACPY3 internally uses the C64x+ GEM's IDMA hardware to initiate QDMA transfers.
    • It shadows the PaRam settings (in some internal memory) and then uses the IDMA to copy them (or DMA them) to the actual EDMA3 PaRam config space and triggers the actual EDMA3 transfer.
    • IDMA requires the source of the IDMA transfer to always be "internal memory". In ACPY3, the IDMA destination address is EDMA3's PaRam configuration space and the source is the shadow PaRam setting (in the form of some ACPY3 internal data structures).
    • Usually DMAN3 is used to provide memory requested by ACPY3. If DMAN3's configuration parameter DMAN3.heapInternal is set incorrectly (to external memory), then the IDMA transfer will not succeed, hence the actual EDMA transfer never starts and this leads to a hang when ACPY3_wait() is called by the application.
  • Another slightly obscure reason for an ACPY3_wait() hang is the wrong usage of the waitId in the ACPY3_waitLinked() calls. The waitId's are to be used as follows:
    • waitId of -1 can be passed in the ACPY3_Params to indicate that no intermediate waits will be made on this linked transfer. Use this in your ACPY3_Params for intermediate transfers that you don't intend to wait on.
    • 0 <= waitId < (numWaits - 1), where numWaits is the parameters you supplied in IDMA3_ChannelRec when creating the IDMA3 handle, can be passed to ACPY3_Params to indicate that this intermediate transfer can be "waited" on by an ACPY3_waitLinked() call.
    • For a single transfer configured (using ACPY3_configure()) or for the last transfer in a series of linked transfers, internally a waitId of (numWaits -1) is automatically used. Any supplied waitId will be ignored. Do not use this waitId for any intermediate transfers.
    • Please refer to the DMAN3/ACPY3 User's Guide for more details.

Does ACPY3 support 3D transfers?

No, ACPY3 does not support 3D transfers, since it uses QDMA channels only.

If you want to do a 3D transfer, you can use a DMA channel, and chain it to itself (set the TCC bits of the PaRam opts to the DMA channel number). Set the synchronization type to ABSYNC, the STATIC bit to 0, and set ITCHEN to 1 in the PaRam opts.

RMAN Questions

Where's the RMAN User's Guide?

The RMAN User's Guide is here.

The FC API Reference Guide also includes RMAN API documentation.

How do I configure the EDMA3 resource manager with specific resources (channels, params, tccs) so that the algorithms can request them?

Use the ti.sdo.fc.edma3.Settings module to designate the EDMA3 resources to be used by the RMAN module. This article describes the available configuration settings.

One key field is the 'regionConfig' field, which can be used to designate the exact EDMA3 channels to be used. A good example of how to use this field is provided in the Framework Components example scratchEdma3 located in $(FC_INSTALL_DIR)/examples/ti/sdo/fc/rman/examples/scratchEdma3 of your FC installation.