Qualité de service

À partir d'Android 11, NNAPI offre une meilleure qualité de service (QoS) en permettant à une application d'indiquer les priorités relatives de ses modèles, le temps maximal attendu pour préparer un modèle donné et la durée maximale de temps attendue pour effectuer une exécution donnée. De plus, Android 11 introduit des valeurs d'erreur NNAPI supplémentaires permettant à un service d'indiquer plus précisément ce qui s'est mal passé en cas de défaillance afin que l'application cliente puisse mieux réagir et récupérer.

Priorité

Pour Android 11 ou version ultérieure, les modèles sont préparés avec une priorité dans NN HAL 1.3. Cette priorité est relative aux autres modèles préparés appartenant à la même application. Les exécutions de priorité supérieure peuvent utiliser plus de ressources de calcul que les exécutions de priorité inférieure, et peuvent préempter ou priver les exécutions de priorité inférieure.

L'appel NN HAL 1.3 qui inclut Priority comme argument explicite est IDevice::prepareModel_1_3. Notez que IDevice::prepareModelFromCache_1_3 inclut implicitement Priority dans les arguments de cache.

Il existe de nombreuses stratégies possibles pour prendre en charge les priorités en fonction des fonctionnalités du pilote et de l'accélérateur. Voici quelques stratégies:

  • Pour les pilotes qui disposent d'une prise en charge intégrée de la priorité, propagez directement le champ Priority à l'accélérateur.
  • Utilisez une file d'attente de priorités par application pour prendre en charge différentes priorités avant même qu'une exécution atteigne l'accélérateur.
  • Mettez en veille ou annulez les modèles à faible priorité en cours d'exécution pour libérer l'accélérateur d'exécuter des modèles à priorité élevée. Pour ce faire, insérez des points de contrôle dans les modèles à faible priorité qui, lorsqu'ils sont atteints, interrogent un indicateur pour déterminer si l'exécution en cours doit être arrêtée prématurément, ou en partitionnant le modèle en sous-modèles et en interrogeant l'indicateur entre les exécutions de sous-modèles. Notez que l'utilisation de points de contrôle ou de sous-modèles dans les modèles préparés avec une priorité peut entraîner des frais supplémentaires qui ne sont pas présents pour les modèles sans priorité dans les versions antérieures à NN HAL 1.3.

    • Pour prendre en charge la préemption, conservez le contexte d'exécution, y compris l'opération ou le sous-modèle suivant à exécuter, ainsi que toutes les données d'opérandes intermédiaires pertinentes. Utilisez ce contexte d'exécution pour reprendre l'exécution ultérieurement.
    • La prise en charge complète de la préemption n'est pas nécessaire. Le contexte d'exécution n'a donc pas besoin d'être conservé. Les exécutions du modèle NNAPI étant déterministes, elles peuvent être redémarrées à partir de zéro ultérieurement.

Android permet aux services de différencier les différentes applications appelantes à l'aide d'un AID (Android UID). HIDL dispose de mécanismes intégrés pour récupérer l'UID de l'application appelante via la méthode ::android::hardware::IPCThreadState::getCallingUid. Vous trouverez une liste des AID dans libcutils/include/cutils/android_filesystem_config.h.

Dates limites

À partir d'Android 11, la préparation et l'exécution des modèles peuvent être lancées avec un argument de délai OptionalTimePoint. Pour les pilotes qui peuvent estimer la durée d'une tâche, cette échéance leur permet d'arrêter la tâche avant son début s'ils estiment qu'elle ne peut pas être terminée avant la date limite. De même, l'échéance permet au pilote d'abandonner une tâche en cours qu'il estime ne pas pouvoir terminer avant la date limite. L'argument "deadline" n'oblige pas un pilote à abandonner une tâche si elle n'est pas terminée à la date limite ou si la date limite est passée. L'argument "deadline" peut être utilisé pour libérer des ressources de calcul dans le pilote et rendre le contrôle à l'application plus rapidement que possible sans l'échéance.

Les appels NN HAL 1.3 qui incluent des délais OptionalTimePoint comme argument sont les suivants:

  • IDevice::prepareModel_1_3
  • IDevice::prepareModelFromCache_1_3
  • IPreparedModel::execute_1_3
  • IPreparedModel::executeSynchronously_1_3
  • IPreparedModel::executeFenced

Pour voir une implémentation de référence de la fonctionnalité de délai pour chacune des méthodes ci-dessus, consultez l'exemple de pilote NNAPI à l'adresse frameworks/ml/nn/driver/sample/SampleDriver.cpp.

Codes d'erreur

Android 11 inclut quatre valeurs de code d'erreur dans NN HAL 1.3 pour améliorer le signalement des erreurs, ce qui permet aux pilotes de mieux communiquer leur état et aux applications de récupérer plus facilement. Voici les valeurs de code d'erreur dans ErrorStatus.

  • MISSED_DEADLINE_TRANSIENT
  • MISSED_DEADLINE_PERSISTENT
  • RESOURCE_EXHAUSTED_TRANSIENT
  • RESOURCE_EXHAUSTED_PERSISTENT

Sous Android 10 ou version antérieure, un pilote ne pouvait indiquer une défaillance que via le code d'erreur GENERAL_FAILURE. À partir d'Android 11, les deux codes d'erreur MISSED_DEADLINE peuvent être utilisés pour indiquer que la charge de travail a été interrompue parce que l'échéance a été atteinte ou parce que le pilote a prédit que la charge de travail ne serait pas terminée avant l'échéance. Les deux codes d'erreur RESOURCE_EXHAUSTED peuvent être utilisés pour indiquer que la tâche a échoué en raison d'une limitation de ressources dans le pilote, par exemple si le pilote ne dispose pas de suffisamment de mémoire pour l'appel.

La version TRANSIENT des deux erreurs indique que le problème est temporaire et que les futurs appels à la même tâche peuvent aboutir après un court délai. Par exemple, ce code d'erreur doit être renvoyé lorsque le pilote est occupé par une tâche précédente de longue durée ou nécessitant beaucoup de ressources, mais que la nouvelle tâche aboutirait si le pilote n'était pas occupé par la tâche précédente. La version PERSISTENT des deux erreurs indique que les futurs appels à la même tâche devraient toujours échouer. Par exemple, ce code d'erreur doit être renvoyé lorsque le pilote estime que la tâche ne sera pas terminée d'ici la date limite, même dans des conditions parfaites, ou que le modèle est intrinsèquement trop volumineux et dépasse les ressources du pilote.

Validation

La fonctionnalité de qualité de service est testée dans les tests VTS NNAPI (VtsHalNeuralnetworksV1_3Target). Cela inclut un ensemble de tests de validation (TestGenerated/ValidationTest#Test/) pour s'assurer que le pilote rejette les priorités non valides et un ensemble de tests appelés DeadlineTest (TestGenerated/DeadlineTest#Test/) pour s'assurer que le pilote gère correctement les échéances.