Brevet FR3142815A1 — publié le 20240607

Circuit de calcul (4) comportant au moins une chaîne de calcul (6) comprenant une pluralité de blocs de calcul (7) comportant chacun un multiplieur (9) et un accumulateur (10), le circuit de calcul étant agencé pour appliquer sur les premières entrées des multiplieurs une succession de données primaires formant au moins un vecteur primaire, et appliquer sur les deuxièmes entrées des multiplieurs une succession de séries de données secondaires formant des vecteurs secondaires, la chaîne de calcul étant ainsi agencée pour produire successivement des résultats de multiplications du au moins un vecteur primaire par chaque vecteur secondaire. FIGURE DE L’ABREGE : Fig.5 Structure de parallélisation de convolution à bas besoin de bande passante L’invention concerne le domaine des circuits de calcul utilisés par exemple pour calculer des produits de convolution dans des réseaux de neurones. ARRIERE PLAN DE L’INVENTION L’utilisation des modèles de Deep Learning (apprentissage profond) et, en particulier, des modèles du type réseau de neurones convolutif, nécessite de réaliser un nombre important de calculs de produits de convolution. La capacité des composants hardware (matériel) à réaliser de manière efficace ces calculs est un enjeu majeur pour le développement des applications utilisant cette technologie. Cet enjeu concerne l’entraînement du modèle, mais aussi et surtout l’exécution de l’inférence, qui peut être mise en œuvre dans un système embarqué et donc avec des ressources limitées (puissance de calcul, bande passante de données, énergie disponible, etc.). On envisage de développer un circuit de calcul, implémenté par exemple dans un FPGA (pour Field Programmable Gate Arrays ) ou un ASIC (pour Application Specific Integrated Circuit ), qui soit le plus performant possible pour réaliser ces calculs de produits de convolution. L’opération de base de la convolution est l’opération combinée MAC, pour Multiplication-ACcumulation. Cette opération consiste à multiplier une donnée par un poids et à additionner le résultat de la multiplication avec les résultats des multiplications précédentes. Or, on a constaté que, dans les circuits de calcul de l’art antérieur conçus pour calculer des convolutions de réseaux de neurones, le rendement des multiplieurs est assez faible, parfois seulement de 10 %. Cela signifie que les multiplieurs passent 90 % du temps à ne rien faire d’utile. Ceci est très problématique car cela augmente le temps de traitement et la consommation du composant implémentant le circuit de calcul. Ce faible rendement est dû à une « famine » de données d’entrée : les mémoires intégrées dans ou reliées au composant réalisant le circuit de calcul ne peuvent pas fournir suffisamment rapidement les données aux multiplieurs. Augmenter le rendement, et donc l’efficacité de l’implémentation de ces calculs, nécessite impérativement de réduire le besoin en bande passante. En référence à la , la structure traditionnelle pour réaliser les calculs de convolutions dans les réseaux de neurones est une architecture systolique, qui est une structure 2D (deux dimensions). Dans l’exemple de la , a et b sont des matrices 3x3. Chaque carré représente un Processeur Elémentaire (PE). A chaque cycle d’horloge, chaque PE : multiplie les deux entrées (haut et gauche) ; accumule le résultat de la multiplication localement ; transfère les coefficients a i,j et b i,j respectivement vers la droite et vers le bas. Ainsi, après deux coups d’horloge, le premier PE a réalisé deux MAC (c’est le cas sur la ). Ses deux voisins ont réalisé un MAC, car ils reçoivent les données avec un décalage d’un cycle d’horloge. Au bout de trois cycles d’horloge, le premier PE a calculé l’équation : a 0,0 x b 0,0 + a 0,1 x b 1,0 + a 0,2 x b 2,0 Cette équation correspond à la multiplication du vecteur a 0,x avec le vecteur b y,0 . Au bout de sept cycles d’horloge, la totalité des multiplications de vecteurs a été réalisée, ce qui correspond à une multiplication de deux matrices 3x3 réalisée en sept cycles d’horloge. Avec cette structure pipelinée et en envoyant les données de la matrice suivante au plus tôt, il est même possible de calculer une multiplication de deux matrices 3x3 tous les trois cycles d’horloge. L’architecture systolique nécessite une faible bande passante des données d’entrée, car elle maximise la réutilisation des données d’entrée dans les calculs (chaque donnée de l’une des deux entrées est multipliée par toute les données de l’autre entrée). Cependant, cette architecture implique un déplacement des données dans la structure, ce qui peut nécessiter beaucoup de ressources (registres). Sa mise en œuvre nécessite par ailleurs beaucoup de bande passante et/ou beaucoup de ressources pour produire les données de sortie. Une autre structure couramment utilisée est la structure de type Tensor Cores , qui est une structure 3D. Cette structure présente l’avantage de nécessiter (à peu près) la même bande passante en entrée et en sortie. Ceci présente un avantage dans une structure fixe et généraliste (ce qui est le cas par exemple des GPUs, pour Graphics Processing Units , ou des processeurs multicoeurs), car cela permet de manipuler des données de tailles homogènes en entrée et sortie, permettant un dimensionnement simple et homogène des bus de transmission, des registres, des mémoires, etc. L’inconvénient de cette structure est qu’elle nécessite une bande passante plus élevée, car chaque donnée d’entrée est moins réutilisée (une donnée d’une entrée n’est multipliée que par une partie des données venant de l’autre entrée). La structure ne maximise donc pas les calculs réalisés : elle requiert plus de bande passante au total et présente une consommation plus élevée (car plus de déplacements). OBJET DE L’INVENTION L’invention a pour objet de réaliser un grand nombre de multiplications-accumulations, tout en limitant le besoin en bande passante et les ressources utilisées. En vue de la réalisation de ce but, on propose un circuit de calcul comportant au moins une chaîne de calcul comprenant une pluralité de blocs de calcul comportant chacun un multiplieur comprenant une première entrée et une deuxième entrée, et un accumulateur comprenant une première entrée reliée à une sortie du multiplieur, le circuit de calcul étant agencé pour, de manière cadencée par des cycles d’horloge, appliquer sur les premières entrées des multiplieurs des blocs de calcul de ladite chaîne de calcul une succession de données primaires formant au moins un vecteur primaire, et appliquer sur les deuxièmes entrées des multiplieurs des blocs de calcul de ladite chaîne de calcul une succession de séries de données secondaires formant des vecteurs secondaires, chaque bloc de calcul de ladite chaîne de calcul étant agencé pour, à chaque cycle d’horloge, additionner un résultat d’une multiplication réalisée par ledit bloc de calcul avec une valeur accumulée au cycle d’horloge précédent par l’accumulateur dudit bloc de calcul ou d’un autre bloc de calcul de ladite chaîne de calcul, la chaîne de calcul étant ainsi agencée pour produire successivement des résultats de multiplications du au moins un vecteur primaire par chaque vecteur secondaire. Le circuit de calcul selon l’invention permet de maximiser la parallélisation des calculs en minimisant la quantité nécessaire de données d’entrée. Les données d’entrée (premières, deuxièmes et troisièmes données) sont utilisées le plus grand nombre de fois possible (multiplication de chaque donnée du premier vecteur et du deuxième vecteur par chaque donnée de chaque troisième vecteur), ce qui minimise la bande passante requise des données d’entrée. Le décalage temporel de la disponibilité des résultats en sortie de la chaîne de calcul permet de réduire la bande passante en sortie et/ou les ressources de stockage et/ou de routage nécessaires pour les données de sortie. La bande passante instantanée en sortie est minimisée, car il n’y a pas de « pics » de bande passante qui seraient complexes à gérer. Le circuit de calcul permet de minimiser les ressources utilisées et donc, pour une même application, soit de mettre en œuvre l’application avec des composants plus petits, soit, pour une même taille de composant, de mettre en œuvre l’application de manière plus performante. On propose de plus un circuit de calcul tel que précédemment décrit, comprenant un nombre N de chaînes de calcul formant des lignes d’une structure matricielle, chaque chaîne de calcul comprenant un nombre M de blocs de calcul, les deuxièmes entrées des multiplieurs des blocs de calcul d’une même colonne de ladite structure matricielle étant connectées entre elles. On propose de plus un circuit de calcul tel que précédemment décrit, chaque bloc de calcul de chaque chaîne de calcul comportant un premier multiplexeur comprenant une première entrée et une deuxième entrée, la première entrée du multiplieur dudit bloc de calcul étant reliée à une sortie dudit premier multiplexeur, les premières entrées des premiers multiplexeurs des blocs de calcul de ladite chaîne de calcul étant reliées entre elles et les deuxièmes entrées des premiers multiplexeurs des blocs de calcul de ladite chaîne de calcul étant reliées entre elles, le circuit de calcul étant agencé pour appliquer sur les premières entrées desdits premiers multiplexeurs une succession de premières données primaires formant un premier vecteur primaire, appliquer sur les deuxièmes entrées desdits premiers multiplexeurs une succession de deuxièmes données primaires formant un deuxième vecteur primaire, la chaîne de calcul étant agencée pour produire successivement et en série des résultats de multiplications du premier vecteur primaire par chaque vecteur secondaire puis du deuxième vecteur primaire par chaque vecteur secondaire. On propose de plus un circuit de calcul tel que précédemment décrit, chaque bloc de calcul de chaque chaîne de calcul comprenant un deuxième multiplexeur agencé de sorte que : - une sortie dudit deuxième multiplexeur est reliée à une deuxième entrée de l’accumulateur dudit bloc de calcul ; - une sortie dudit accumulateur étant reliée à une première entrée dudit deuxième multiplexeur ; - une sortie dudit accumulateur étant relié à une première entrée d’un bloc suivant de ladite chaîne de calcul. On propose de plus un circuit de calcul tel que précédemment décrit, dans lequel les blocs de calcul de chaque chaîne de calcul comprennent un bloc d’entrée, un bloc de sortie et des blocs intermédiaires positionnés entre le bloc d’entrée et le bloc de sortie, la chaîne de calcul étant agencée de sorte qu’une sortie de l’accumulateur de chacun des bloc d’entrée et blocs intermédiaires est reliée à une deuxième entrée de l’accumulateur d’un bloc suivant de ladite chaîne de calcul. On propose de plus un circuit de calcul tel que précédemment décrit, dans lequel la sortie de l’accumulateur du bloc de sortie est reliée à une deuxième entrée de l’accumulateur du bloc d’entrée. On propose de plus un circuit de calcul tel que précédemment décrit, dans lequel chaque chaîne de calcul comprend un multiplexeur de sortie, ladite chaîne de calcul étant agencée de sorte que, pour chaque bloc de calcul, la sortie de l’accumulateur dudit bloc de calcul est reliée à une entrée distincte du multiplexeur de sortie. On propose de plus un circuit de calcul tel que précédemment décrit, dans lequel chaque chaîne de calcul comprend en outre un accumulateur de sortie ayant une première entrée reliée à la sortie de l’accumulateur d’un bloc de sortie de ladite chaîne de calcul. On propose de plus un circuit de calcul tel que précédemment décrit, dans lequel chaque chaîne de calcul comprend en outre un accumulateur de sortie ayant une première entrée reliée à la sortie du multiplexeur de sortie de ladite chaîne de calcul. On propose de plus un circuit de calcul tel que précédemment décrit, comprenant en outre un premier buffer relié à la première entrée du premier multiplexeur d’un bloc d’entrée de la chaîne de calcul, et un deuxième buffer relié à la deuxième entrée du premier multiplexeur du bloc d’entrée de la chaîne de calcul. On propose de plus un circuit de calcul tel que précédemment décrit, comprenant en outre un troisième buffer ayant une entrée reliée à une sortie de l’accumulateur de sortie et une sortie reliée à une deuxième entrée de l’accumulateur de sortie. On propose de plus un circuit de calcul tel que précédemment décrit, comprenant un bloc de mémoire vive primaire pour chaque chaîne de calcul, et une pluralité de blocs de mémoire vive secondaires, les données primaires et les données secondaires étant appliquées pour chaque chaîne de calcul respectivement via le bloc de mémoire vive primaire associé à ladite chaîne de calcul et via les blocs de mémoire vive secondaires, les blocs de mémoire vive primaires et les blocs de mémoire vive secondaires permettant de fournir aux chaînes de calcul plusieurs fois des mêmes données primaires ou secondaires sans avoir besoin d’accéder à chaque fois à une ou des sources de données desquelles proviennent les données primaires et les données secondaires. On propose de plus un circuit de calcul tel que précédemment décrit, le circuit de calcul étant configuré pour effectuer un produit de convolution d’un tenseur d’entrée par un masque de taille N masque pour obtenir un tenseur de sortie, le circuit de calcul étant tel que : N masque = K.M, où K est un entier positif. On propose de plus un circuit de calcul tel que précédemment décrit, le circuit de calcul étant agencé pour : - appliquer les séries de données secondaires selon une séquence cyclique prédéfinie ; - démarrer l’application des premières données primaires sur les premières entrées des premiers multiplexeurs puis, après un nombre prédéfini de cycles d’horloge, démarrer l’application des deuxièmes données primaires sur les deuxièmes entrées des premiers multiplexeurs ; - piloter les premiers multiplexeurs de sorte que la chaîne de calcul, simultanément, termine une multiplication du premier vecteur primaire par chacun des vecteurs secondaires et débute une multiplication du deuxième vecteur primaire par chacun des vecteurs secondaires. On propose de plus un circuit de calcul tel que précédemment décrit, les vecteurs secondaires formant une matrice, la séquence cyclique prédéfinie comportant des cycles comprenant chacun une première phase au cours de laquelle les séries de données secondaires comprennent un nombre croissant de composantes de lignes ou de colonnes successives de la matrice, une deuxième phase au cours de laquelle les séries de données secondaires comprennent un nombre constant de composantes de lignes ou de colonnes successives de la matrice, et une troisième phase au cours de laquelle les séries de données secondaires comprennent un nombre décroissant de composantes de lignes ou de colonnes successives de la matrice. On propose de plus un circuit de calcul tel que précédemment décrit, dans lequel le circuit de calcul comprend plusieurs chaînes de calcul et un multiplexeur additionnel ayant une ou des entrées reliées à un ou des accumulateurs d’un ou de blocs de calcul de la même chaîne de calcul et/ou d’une autre chaîne de calcul. On propose de plus un circuit de calcul tel que précédemment décrit, comprenant une pluralité de structures de calcul comprenant chacune une pluralité de chaînes de calcul, les structures de calcul étant arrangées selon une architecture pipeline. On propose de plus un circuit de calcul tel que précédemment décrit, chaque structure de calcul étant agencée pour effectuer des produits de convolution pour une couche de convolution distincte d’un modèle de réseau de neurones. On propose de plus un composant électronique dans lequel est réalisé le circuit de calcul tel que précédemment décrit. On propose de plus un composant électronique tel que précédemment décrit, le composant électronique étant un FPGA. On propose de plus un composant électronique tel que précédemment décrit, le FPGA comprenant des blocs DSP, chaque bloc de calcul étant réalisé dans un bloc DSP. On propose de plus un composant électronique tel que précédemment décrit, le circuit de calcul comprenant au moins une structure de calcul présentant une architecture matricielle comprenant une pluralité de chaînes de calcul formant des lignes de l’architecture matricielle, le circuit de calcul comprenant des blocs DSP dans chacun desquels sont réalisés deux blocs de calcul de deux lignes successives. On propose de plus un composant électronique tel que précédemment décrit, le composant électronique étant un ASIC. L’invention sera mieux comprise à la lumière de la description qui suit de modes de mise en œuvre particuliers non limitatifs de l’invention. Il sera fait référence aux dessins annexés parmi lesquels : la illustre un produit de convolution de matrices réalisé dans une architecture systolique ; la représente le produit de convolution d’un tenseur d’entrée par un masque ; la représente un exemple de bloc DSP ; la représente une structure de calcul ; la représente une chaîne de calcul selon un premier mode de réalisation ; la représente la chaîne de calcul sans les multiplexeurs ; la illustre les calculs réalisés par une chaîne de calcul qui n’aurait pas de multiplexeurs ; la correspond à la troisième et dernière colonne de la , mais dans une structure à multiplexeur ; la représente un pipeline de structures de calcul ; la représente une chaîne de calcul selon un deuxième mode de réalisation ; la représente une chaîne de calcul selon un troisième mode de réalisation ; la représente un exemple de bloc DSP pour mettre en œuvre un bloc de calcul de la chaîne de calcul de la . DESCRIPTION DETAILLEE DE L’INVENTION Le circuit de calcul selon l’invention est ici utilisé pour effectuer des calculs de produits de convolution 3D, dans un réseau de neurones comprenant une pluralité de couches de convolution. En référence à la , le circuit de calcul calcule donc des produits de convolution entre un tenseur d’entrée 1 et un ou des masques 2 (ou noyaux) pour obtenir un tenseur de sortie 3. Dans le cas de la première couche de convolution d’un réseau de neurones, le tenseur d’entrée 1 est par exemple une image d’entrée acquise par un dispositif de capture d’images (caméra par exemple), éventuellement prétraitée, et ayant une largeur l, une hauteur h et une profondeur p. La profondeur p est par exemple égale à trois pour une image couleur, correspondant aux composantes RVB (Rouge, Vert, Bleu). Le nombre de canaux du tenseur d’entrée 1 est égal à sa profondeur p. On appelle pixel la « carotte » du tenseur d’entrée 1 de coordonnées (x,y). Chaque pixel comprend un nombre de sous-pixels égal au nombre de canaux du tenseur d’entrée 1. Le sous-pixel est le constituant élémentaire du pixel. Il s’agit d’une donnée de dimension 1, qui est codée par exemple en INT8, et qui a pour coordonnées (x, y, c), où c est la coordonnée du canal correspondant du tenseur d’entrée. C’est le sous-pixel qui est multiplié par un poids (scalaire) dans la convolution. Chaque masque 2 a généralement le même nombre de canaux que le tenseur d’entrée 1, sauf dans le cas d’une convolution dite Depthwise qui consiste à appliquer un masque unique sur chaque canal d’un tenseur d’entrée (on commence aussi à trouver des masques de profondeurs intermédiaires). Le nombre de canaux du tenseur de sortie 3 est égal au nombre de masques 2. On décrit tout d’abord un mode de réalisation, dans lequel le circuit de calcul est mis en œuvre dans un FPGA. L’utilisation d’un FPGA est particulièrement pertinente dans le cas d’une architecture spécialisée, dédiée à un modèle particulier de réseau de neurones. Cette architecture doit être performante pour un seul réseau, qui est connu à la conception du circuit de calcul. C’est sur ce principe que repose classiquement la conception sur FPGA, car l’architecture implémentable dans le FPGA est libre. Intrinsèquement, le FPGA est moins rapide qu’un ASIC, et présente une fréquence de fonctionnement moyenne. Mais la spécialisation de l’architecture pour les fonctions à réaliser le rend très performant : plutôt qu’une puissance brute élevée et une efficacité faible, le FPGA a une puissance brute moyenne (comparée à celle d’un ASIC) et une efficacité élevée. Le FPGA utilisé comprend ici une pluralité de blocs DSP (DSP pour Digital Signal Processing , ou Traitement Numérique du Signal), qui sont des blocs élémentaires et identiques. Le FPGA comprend par exemple 2928 blocs DSP semblables à celui visible sur la . En référence à la , le circuit de calcul 4 comporte une pluralité de structures de calcul 5 comprenant chacune une pluralité de chaînes de calcul 6. Dans une même structure de calcul 5, toutes les chaînes de calcul 6 sont identiques et fonctionnent de la même manière. Chaque structure de calcul 5 présente une architecture matricielle comprenant N lignes, et donc N chaînes de calcul 6, et M colonnes. On considère que la structure de calcul 5 comporte deux entrées principales : une première entrée principale EP1, par laquelle des vecteurs de données sont introduits horizontalement dans la structure de calcul 5, et une deuxième entrée principale EP2, par laquelle des vecteurs de données sont introduits verticalement dans la structure de calcul 5. Les vecteurs de données ont des tailles prédéfinies et potentiellement différentes. On parlera ici de données primaires pour parler des données introduites horizontalement, et de données secondaires pour parler des données introduites verticalement (les termes « primaire » et « secondaire » n’ont pas d’autre signification que celle-ci). Pour maximiser le nombre d’opérations réalisées, une structure 2D est utilisée. Chaque donnée d’un vecteur de données de l’une des entrées principales est multipliée par chaque donnée du vecteur de données de l’autre entrée principale. Cette structure permet de minimiser le besoin en bande passante entrante en maximisant la réutilisation des données (contrairement aux structures 3D). Par exemple, selon la structure de l’invention, pour réaliser n MAC par cycle d’horloge, il faut fournir 2x√n données. Ainsi, si n = 256 (256 multiplications par cycle), il faut fournir 2x16 opérandes par cycle. Dans l’architecture matricielle de la structure de calcul 5, le nombre de lignes N est donc égal à √n (soit 16 dans notre exemple) et le nombre de colonnes M est aussi égal à √n (soit 16 dans notre exemple). Les données secondaires introduites par la deuxième entrée principale EP2 sont ici des poids, c’est-à-dire des composantes de masques. Le nombre de lignes N est par exemple égal au nombre de pixels du tenseur d’entrée 1 (mais pas nécessairement), et le nombre de colonnes M est par exemple égal au nombre de canaux du tenseur de sortie 3, et donc au nombre de masques 2 (mais pas nécessairement). A chaque cycle d’horloge, on fournit donc un sous-pixel d’un canal d’entrée pour chacun des N pixels du tenseur d’entrée, et un poids pour chacun des M canaux de sortie. Le calcul nécessite donc un nombre de coups d’horloge égal au nombre de poids du masque pour calculer NxM sous-pixels de sortie, c’est dire M sous-pixels de N pixels. Les sous-pixels de sortie complétement calculés sortent en fin de chaîne à chaque coup d’horloge si le nombre de canaux du tenseur de sortie est égal à M. Sinon, comme on le verra plus bas, une post-accumulation est réalisée. Il s’agit d’une structure de type systolique mais sans la propagation des informations en entrée de proche en proche ; cette structure minimise le besoin en bande passante entrante. Typiquement, les poids sont stockés en interne du FPGA et les données (sous-pixels du tenseur d’entrée) sont « streamées » (c’est-à-dire transmises successivement selon un flux continu). En référence à la , chaque chaîne de calcul 6 comporte un nombre M de blocs de calcul 7. Les blocs de calcul 7 comprennent un bloc d’entrée 7a, un bloc de sortie 7b et des blocs intermédiaires 7c positionnés entre le bloc d’entrée 7a et le bloc de sortie 7b. Chaque bloc de calcul 7 comporte un premier multiplexeur 8, un multiplieur 9 et un accumulateur 10 (ou additionneur). Le premier multiplexeur 8, le multiplieur 9 et l’accumulateur 10 comprennent chacun une première entrée E1, une deuxième entrée E2 et une sortie S. La première entrée E1 du multiplieur 9 est reliée à la sortie S du premier multiplexeur 8. La première entrée E1 de l’accumulateur 10 est reliée à la sortie S du multiplieur 9. Les premières entrées E1 des premiers multiplexeurs 8 de tous les blocs de calcul 7 sont reliées entre elles, et les deuxièmes entrées E2 des premiers multiplexeurs 8 sont reliées entre elles, ce qui parallélise la structure de la chaîne de calcul 6. La sortie S de l’accumulateur 10 de chacun des blocs d’entrée 7a et blocs intermédiaires 7c est reliée à la deuxième entrée E2 de l’accumulateur 10 du bloc 7 suivant. La sortie S de l’accumulateur 10 du bloc de sortie 7b est reliée à la deuxième entrée E2 de l’accumulateur 10 du bloc d’entrée 7a. La chaîne de calcul 6 comprend en outre un accumulateur de sortie 11 ayant une première entrée E1 reliée à la sortie S de l’accumulateur 10 du bloc de sortie 7b. La chaîne de calcul 6 comprend aussi un premier buffer 12(ou mémoire tampon) relié à la première entrée E1 du multiplexeur 8 du bloc d’entrée 7a, un deuxième buffer 14 relié à la deuxième entrée E2 du premier multiplexeur 8 du bloc d’entrée 7a, et un troisième buffer 15 ayant une entrée reliée à une sortie S de l’accumulateur de sortie 11 et une sortie reliée à une deuxième entrée E2 de l’accumulateur de sortie 11. On comprend donc que le circuit de calcul 4 comprend un nombre N de chaînes de calcul 6 formant des lignes d’une structure matricielle, et que chaque chaîne de calcul 6 comprend un nombre M de blocs de calcul 7. Les deuxièmes entrées E2 des multiplieurs 9 des blocs de calcul 7 d’une même colonne sont connectées entre elles. Le circuit de calcul 4 (et donc chaque chaîne de calcul 6) est relié à une source 16 qui fournit les données d’entrée (données primaires et secondaires). La source 16 est ici une source externe au FPGA, par exemple une mémoire externe, non intégrée dans le FPGA (mémoire de type DDR4 ou autre), mais il pourrait s’agir d’un autre élément, et par exemple d’un buffer interne au FPGA, d’un bloc de calcul, etc. Le circuit de calcul 4 comprend de plus des blocs de mémoire vive primaires 17 et des blocs de mémoire vive secondaires 18 (RAM). Les blocs 17 et les blocs 18 sont ici des mémoires internes au FPGA et sont reliés à la source 16. Les données primaires et les données secondaires sont appliquées pour chaque chaîne de calcul 6 respectivement via le bloc 17 associé à ladite chaîne de calcul et via les blocs 18. Les blocs 17, 18 permettent de fournir aux chaînes de calcul 6 plusieurs fois des mêmes données primaires ou secondaires sans avoir besoin d’accéder à chaque fois à la source 16 de laquelle proviennent les données primaires et les données secondaires. En effet, la mémoire externe (DDR) est « lente » comparée au besoin interne. D’autre part, comme on ne calcule que « M » canaux à la fois, il faut faire plusieurs séquences de calcul si le nombre de canaux est supérieur à M. Dans ce cas, il faut relire les données entrantes autant de fois qu’il y a de séquence de calcul. Plutôt que de solliciter la DDR externe (lente et consommant beaucoup d’énergie), on a « tamponné » ces données en RAM interne pour les refournir. Ceci s’applique aussi pour des masques 3x3xn (ou plus). Un même pixel participe au calcul des 8 pixels voisins (en plus de lui-même). Il faudrait donc lire les mêmes données 9 fois x nombre de séquence de calcul. Pour les blocs 18 (typiquement les poids), il faut relire les poids pour chaque nouveau groupe de N pixels à traiter. Chaque chaîne de calcul 6 comporte ainsi un bloc 17 comprenant une sortie reliée à l’entrée du premier buffer 12 et à l’entrée du deuxième buffer 14. Le circuit de calcul 4 comprend autant de blocs 18 que de blocs de calcul 7 par chaîne de calcul 6. Ainsi, en se référant à l’architecture matricielle de la structure de calcul 5, la structure de calcul 5 comprend N p blocs 17 et M blocs 18. La sortie de chaque bloc 18 est reliée aux deuxièmes entrées E2 des multiplieurs 9 des blocs de calcul 7 de la colonne correspondante. Les données primaires appliquées en entrée de chaque chaîne de calcul 6, via le bloc mémoire 17 associé, sont donc issues du tenseur d’entrée 1 (qui est ici une image en 3D). Les données secondaires appliquées via les blocs 18 sont des poids d’un masque 2. On note qu’il serait possible d’appliquer les poids en entrée des chaînes de calcul 6, via les blocs 17, et les données issues du tenseur d’entrée 1 via les blocs 18. Un sous-pixel du canal du tenseur d’entrée sera donc lu plusieurs fois dans le bloc 17, le premier buffer 12 et le deuxième buffer 14, ce qui réduit le besoin en bande passante DDR. Le bloc 17 permet de réduire le nombre d’accès à la mémoire externe 16 (DDR). Les buffers 12 et 14 permettent de réduire le nombre d’accès au bloc 17. Ainsi, la DDR 16 a une grosse capacité de mémoire mais une faible bande passante. Le bloc 17 a une capacité de mémoire moyenne et une bande passante moyenne (typiquement réalisé en blocs de RAM dans un FPGA) et les buffers 12 et 14 sont à haute bande passante mais faible capacité (typiquement réalisé en bascules ou en RAM distribuées sur des FPGA Xilinx). On note qu’il n’est pas obligatoire d’avoir la même dimension pour le nombre de lignes N et le nombre de colonne M dans la structure de calcul 5, mais que c’est le carré qui minimise le besoin en bande passante. Pour maximiser le rendement, c’est-à-dire pour que chaque multiplieur réalise une multiplication utile à chaque cycle d’horloge, les valeurs de N et M doivent respecter certaines contraintes : N doit être inférieur ou égal au nombre de canaux de chaque masque et au nombre de canaux du tenseur de sortie ; le nombre de pixels du tenseur d’entrée devrait être un multiple de M ; le nombre d’éléments (sous-pixels) du masque doit être un multiple de N. On explique maintenant la manière dont les calculs sont réalisés. Pour chaque chaîne de calcul 6, le circuit de calcul 4 est agencé pour, de manière cadencée par des cycles d’horloge, appliquer sur les premières entrées des multiplieurs 9 des blocs de calcul 7 de ladite chaîne de calcul 6 une succession de données primaires formant au moins un vecteur primaire, et appliquer sur les deuxièmes entrées des multiplieurs 9 des blocs de calcul 7 de ladite chaîne de calcul 6 une succession de séries de données secondaires formant des vecteurs secondaires. Chaque bloc de calcul 7 de ladite chaîne de calcul 6 est agencé pour, à chaque cycle d’horloge, additionner un résultat d’une multiplication réalisée par ledit bloc de calcul avec une valeur accumulée au cycle d’horloge précédent par l’accumulateur dudit bloc de calcul ou d’un autre bloc de calcul de ladite chaîne de calcul, la chaîne de calcul étant ainsi agencée pour produire successivement des résultats de multiplications du au moins un vecteur primaire par chaque vecteur secondaire. Sur la , chaque bloc de calcul 7 de la chaîne de calcul 6, à chaque cycle d’horloge, additionne un résultat d’une multiplication réalisée par ledit bloc de calcul avec une valeur accumulée au cycle d’horloge précédent par l’accumulateur d’un bloc de calcul précédent de ladite chaîne de calcul. On se place tout d’abord, pour illustrer l’invention, dans une configuration, dans laquelle les blocs de calcul 7 ne comprennent pas de premier multiplexeur 8. Cette configuration est illustrée sur la . Le circuit de calcul 4 applique, de manière cadencée par des cycles d’horloge, une succession de données primaires à l’entrée de chaque chaîne de calcul 6 - et donc, comme il n’y a pas de multiplexeurs 8, ces données sont toutes appliquées sur les premières entrée E1 des multiplieurs 9 : à chaque cycle d’horloge, une nouvelle et même donnée est donc appliquée sur toutes les premières entrées E1 des multiplieurs 9, via le premier bloc mémoire 17 associé à ladite chaîne de calcul 6. De même, à chaque cycle d’horloge, un poids différent est appliqué sur la deuxième entrée E2 de chaque multiplieur 9, via le deuxième bloc mémoire associé 18. A chaque cycle d’horloge, chaque bloc de calcul 7 réalise une multiplication, une accumulation, et le transfert de la donnée contenue dans son accumulateur à l’accumulateur du bloc de calcul suivant. En référence à la , on se place dans le cas où les données primaires comprennent un vecteur de quatre composantes I0 ; I1 ; I2 ; I3, et dans le cas où chaque chaîne de calcul 6 comprend quatre blocs de calcul 7. On cherche ici à réaliser la multiplication d’un pixel du tenseur d’entrée, comprenant quatre sous-pixels (I0 ; I1 ; I2 ; I3), avec six masques de 1x1x4, pour produire un pixel de six canaux en sortie. La n’illustre que le calcul du premier canal de sortie et du début du calcul de deuxième canal. Au premier cycle d’horloge, la composante I0 est appliquée sur les premières entrées E1 des multiplieurs 9, et les poids appliqués (données secondaires) sont : W00 pour le bloc d’entrée 7a, aucun poids sur le premier bloc intermédiaire 7c, aucun poids sur le deuxième bloc intermédiaire 7c, aucun poids sur le bloc de sortie 7b, soit une série de poids que l’on représente de la manière suivante : W00 ; - ; - ; -. Le bloc d’entrée 7a calcule donc I0xW00. Au deuxième cycle d’horloge, la composante I1 est appliquée sur les premières entrées E1 des multiplieurs 9, et les poids appliqués sont : W11 ; W10 ; - ; -. Le bloc d’entrée 7a calcule donc I1xW11. Le premier bloc intermédiaire 7c calcule donc I1xW10 et additionne le résultat de cette multiplication avec le résultat de la multiplication précédente (I0xW00). Les différents calculs réalisés sont visibles sur la pour les cycles d’horloge jusqu’au neuvième cycle. On constate donc qu’à la fin du quatrième cycle d’horloge, le calcul de la multiplication du vecteur primaire comprenant les composantes I0 ; I1 ; I2 ; I3 (vecteur ligne), par le vecteur secondaire comprenant les poids W00 ; W10 ; W20 ; W30 (vecteur colonne), est terminé. De même, à la fin du cinquième cycle d’horloge, le calcul de la multiplication du vecteur comprenant les composantes I0 ; I1 ; I2 ; I3, par le vecteur comprenant les poids W01 ; W11 ; W21 ; W31, est terminé. A la fin du neuvième cycle d’horloge, la chaîne de calcul a donc calculé le produit du vecteur : par chacun des vecteurs de poids : , , , , , . Ainsi, la chaîne de calcul 6, à chaque cycle d’horloge et pour chaque bloc de calcul, accumule le résultat d’une multiplication réalisée par ledit bloc de calcul avec une accumulation réalisée par le bloc de calcul précédent. Pour le bloc d’entrée 7a, le bloc de calcul précédent est le bloc de sortie 7b. Ceci permet de décaler « physiquement » dans la chaîne de calcul 6 les résultats intermédiaires produits au fur et à mesure par chaque bloc de calcul 7, simultanément aux calculs, pour extraire les résultats en série. On étale ainsi dans le temps la disponibilité des résultats. Cette simultanéité permet donc de maximiser les cycles de calculs utiles, tout en minimisant la bande passante en entrée et en sortie pour « extraire » les résultats. On évite un engorgement ou une structure lourde comme dans une architecture systolique. Cette structure présente cependant l’inconvénient d’introduire des « pauses » lors du changement de pixel à traiter (c’est-à-dire lorsque le calcul transite d’un ensemble de données à un autre), ce qui conduit à une perte de performances. Les cycles perdus, visibles sur la , correspondent à des cycles d’horloge au cours desquels les blocs de calcul correspondants ne travaillent pas ; ils occasionnent donc une réduction du rendement. Les premiers multiplexeurs 8 compensent cette faiblesse en permettant un « biseau » sans perte de cycle de calcul entre deux ensembles de données. Les premiers multiplexeurs 8 sont donc optionnels et permettent de maximiser le rendement du calcul. Le circuit de calcul 4, de manière cadencée par des cycles d’horloge, applique sur les premières entrées E1 des premiers multiplexeurs 8 une succession de premières données primaires formant un premier vecteur primaire, applique sur les deuxièmes entrées des multiplexeurs 8 une succession de deuxièmes données primaires formant un deuxième vecteur primaire, et applique sur les deuxièmes entrées E2 des multiplieurs 9 une succession de séries de données secondaires formant des vecteurs secondaires. Ainsi, à chaque cycle d’horloge, une nouvelle première donnée primaire est appliquée sur toutes les premières entrées E1 des premiers multiplexeurs 8, une nouvelle deuxième donnée primaire est appliquée sur toutes les deuxièmes entrées E2 des premiers multiplexeurs 8 (sauf pendant un nombre prédéfini de cycles d’horloge : voir plus bas), et une nouvelle série de données secondaires est appliquée sur les deuxièmes entrées E2 des multiplieurs 9. A chaque cycle d’horloge, chaque bloc de calcul 7 réalise une multiplication, une accumulation, et le transfert de la donnée contenue dans son accumulateur 10 à l’accumulateur 10 du bloc de calcul suivant. Pour le bloc de sortie 7b, le bloc de calcul suivant est le bloc d’entrée 7a. On note que ce rebouclage est optionnel. Il n’est par exemple pas nécessaire dans l’exemple des figures 7 et 8, où le calcul d’une sortie est fini au bout de 4 cycles (donc ne nécessite pas le rebouclage). A chaque cycle d’horloge et pour chaque bloc de calcul 7, la chaîne de calcul 6 accumule donc un résultat d’une multiplication réalisée par ledit bloc de calcul 7 avec une accumulation réalisée par le bloc de calcul précédent, de manière à produire successivement et en série des résultats de multiplications du premier vecteur primaire par chaque vecteur secondaire puis du deuxième vecteur primaire par chaque vecteur secondaire. Pour le bloc d’entrée 7a, le bloc de calcul précédent est le bloc de sortie 7b. Par « série de données secondaires », on entend les données qui, à un cycle d’horloge, sont appliquées sur les différentes deuxièmes entrées des multiplieurs 9 des blocs de calcul 7 de la chaîne de calcul 6 (et donc sur toutes les chaînes de calcul 6 de la structure de calcul 5). Les premières données primaires forment un premier vecteur primaire : , et les deuxièmes données forment un deuxième vecteur primaire : . Le premier vecteur primaire et le deuxième vecteur primaire sont des portions de l’image en 3D (canal particulier de l’image d’entrée). Les données secondaires forment des vecteurs secondaires, qui eux-mêmes forment les vecteurs de poids visibles plus haut. En référence à la , le circuit de calcul 4 applique les séries de données secondaires selon une séquence cyclique prédéfinie. Cette séquence cyclique prédéfinie correspond à la séquence de la . Les séries de données secondaires sont donc appliquées successivement selon la séquence prédéfinie : W00 ; - ; - ; -, W11 ; W10 ; - ; -, W22 ; W21 ; W20 ; -, W33 ; W32 ; W31 ; W30, W04 ; W03 ; W02 ; W01, W15 ; W14 ; W13 ; W12, - ; W25 ; W24 ; W23, - ; - ; W35 ; W34, - ; - ; - ; W35, La séquence cyclique prédéfinie comporte des cycles comprenant chacun une première phase au cours de laquelle les séries de données secondaires comprennent un nombre croissant de composantes de lignes ou de colonnes successives (ici de lignes) d’une matrice comprenant les troisièmes vecteurs, une deuxième phase au cours de laquelle les séries de données secondaires comprennent un nombre constant de composantes de lignes ou colonnes successives (ici de lignes), et une troisième phase au cours de laquelle les séries de données secondaires comprennent un nombre décroissant de composantes de lignes ou colonnes successives (ici de lignes) de ladite matrice. Cette matrice est : . La première phase correspond aux cycles d’horloges 1 à 4. La deuxième phase correspond aux cycles d’horloge 5 et 6. La troisième phase correspond aux cycles d’horloge 7 à 9. Le circuit de calcul 4 démarre l’application des premières données primaires sur les premières entrées E1 des premiers multiplexeurs 8 puis, après un nombre prédéfini de cycles d’horloge, démarre l’application des deuxièmes données primaires sur les deuxièmes entrées E2 des premiers multiplexeurs 8. Ici, le nombre prédéfini est égal à six (car cela correspond au besoin de calculer 6 canaux de sortie par pixel) : le circuit de calcul introduit dans la chaîne de calcul 6 la deuxième donnée I0’ après six cycles d’horloge, soit au septième cycle d’horloge. Le circuit de calcul 4 pilote les premiers multiplexeurs 8 de sorte que la chaîne de calcul 6, simultanément, termine une multiplication du premier vecteur primaire par chacun des vecteurs secondaires et débute une multiplication du deuxième vecteur primaire par chacun des vecteurs secondaires. Ainsi, on voit sur la figure 8 qu’au huitième cycle et au neuvième cycle, la chaîne de calcul 6 finit d’effectuer la multiplication du premier vecteur primaire par le vecteur secondaire et par le vecteur secondaire , et débute la multiplication du deuxième vecteur primaire par le vecteur secondaire , par le vecteur secondaire , par le vecteur secondaire et par le vecteur secondaire . Ainsi, la chaîne de calcul 6 reçoit deux vecteurs de données différents et il est possible de sélectionner quel multiplieur reçoit quel vecteur. Ceci permet « d’entrelacer » les calculs de pixels consécutifs et de ne plus réaliser de pause entre le traitement deux pixels successifs. On maximise ainsi le rendement du circuit de calcul 4. Le rendement le plus élevé possible est obtenu si tous les MAC sont utilisés pour une phase de calcul. On note que le mécanisme de multiplexage est ici inséré pour la première entrée principale EP1 (c’est-à-dire pour les données entrant dans la chaîne de calcul 6 via le bloc 17), mais il serait possible de l’insérer pour la deuxième entrée principale EP2 (c’est-à-dire pour les données entrant dans la chaîne de calcul 6 via les blocs 18). On note que le premier buffer 12, le deuxième buffer 14 et le bloc 17 sont optionnels et dépendent des besoins et des caractéristiques de l’architecture mémoire. Ils permettent de réduire le besoin en bande passante de mémoire RAM (pour les données) et de la DDR4. Il peut être possible de communaliser une mémoire RAM pour plusieurs buffers. Il serait possible d’avoir le même principe pour les poids, un buffer intermédiaire et moins de mémoire RAM (pour les poids), et/ou de streamer les poids depuis la DDR4 si les RAM pour les poids sont de taille insuffisante pour stocker tous les poids. L’accumulateur de sortie 11 est optionnel et indispensable uniquement pour les accumulations trop grandes pour les blocs DSP. En effet, comme on l’a vu plus tôt, les sous-pixels de sortie complétement calculés sortent en fin de chaîne à chaque coup d’horloge si le nombre de canaux est égal à M. Sinon, le troisième buffer 15 et l’accumulateur de sortie 11 permettent de réaliser une post-accumulation. Le sous-pixel calculé est alors disponible en sortie de l’accumulateur 11. La structure de calcul 5 décrite permet d’intégrer deux blocs de calcul par bloc DSP. Sur la , la structure de calcul 5 présente une architecture matricielle comprenant une pluralité de chaînes de calcul 6 formant des lignes de l’architecture matricielle. Le circuit de calcul 4 peut comprendre des blocs DSP dans chacun desquels sont réalisés deux blocs de calcul appartenant à deux lignes successives. Un exemple d’un tel bloc DSP 20 est visible sur la . Pour intégrer deux blocs de calcul par bloc DSP, il faut réaliser les calculs avec des entrées INT8 (il s’agit du type standard pour l’inférence de modèles d’apprentissage profond), et il faut qu’un des deux opérandes soit identique pour les deux multiplications. Il faut donc utiliser le même poids avec deux données, ou la même donnée avec deux poids. Il convient en outre de regrouper les calculs de deux lignes consécutives. Il est aussi possible de regrouper deux colonnes, mais ce regroupement n’est pas compatible du biseau entre pixels (car il faudrait la même valeur ou le même poids pour deux colonnes). On voit sur la le chaînage entre blocs DSPs : le chemin 21 est emprunté par les données entrantes provenant d’un autre bloc DSP, et le chemin 22 est emprunté par les données sortantes vers un autre bloc DSP. On note de plus que la structure avec multiplexeurs permet d’utiliser les multiplieurs à une fréquence deux fois supérieure au reste de la structure. Il serait ainsi possible de diviser par deux le nombre de multiplieurs utilisés en doublant la fréquence des multiplieurs par rapport au reste de la structure (le ratio de deux n’étant qu’un exemple typique). Les deux variantes sont cumulables. La structure de calcul 5 qui vient d’être décrite peut être intégrée dans une architecture pipelinée. En effet, les sorties se font au même rythme que les entrées, ce qui simplifie la structure de bus et permet de chainer les structures entre elles pour une architecture pipelinée. On voit sur la que le circuit de calcul 4 comprend une série de trois structures de calcul 5a, 5b, 5c formant un pipeline de structures. La structure 5a, la structure 5b et la structure 5c réalisent respectivement les calculs de produits de convolution pour une première couche de convolution, une deuxième couche de convolution et une troisième couche de convolution du réseau de neurones. Le fonctionnement de chaque structure de calcul 5, qui vient d’être expliqué, est parfaitement adapté à cette architecture pipelinée. En effet, dès que le résultat du produit de convolution d’un vecteur par un vecteur de la matrice de poids, réalisé par une structure particulière, est disponible, ce résultat peut être utilisé par la structure suivante sans pour autant que les calculs de la structure particulière ne soient terminés. On note que le modèle de réseau de neurones peut présenter des couches intermédiaires entre les couches de convolution (couche d’activation de type ReLu, couche de pooling , couche elementwise , etc.). Les structures représentant ces couches ne sont pas représentées ici mais peuvent être insérées entre les structures 5, conformément aux besoins algorithmiques. Dans le cas d’une architecture développée pour un réseau particulier, il est possible d’adapter la taille des structures aux couches réalisées (tailles des données, tailles des masques, etc.). En particulier, il est possible de sélectionner ces tailles de sorte que le débit et l’ordre des données en entrées et sorties de chaque structure soient les mêmes. Ainsi, le vecteur sortant de la structure 5a est directement transmis à la structure 5b avec le même débit et le même ordre (idem de 5b vers 5c). On note que les structures peuvent avoir besoin de bufferisation des données entrantes ou sortantes, en fonction de la taille des masques et des données (en particulier si le masque utilise plusieurs lignes de pixels de l’image d’entrée). L’architecture pipelinée présente un intérêt élevé pour optimiser la bande passante. En effet, la bande passante d’une mémoire externe, de type DDR par exemple, est relativement faible comparée aux bandes passantes des mémoires internes. Le chaînage des structures en un pipeline permet de réduire les sollicitations de la mémoire externe en transmettant directement les données d’un étage de calcul à un autre, sans passer par la DDR. Il faut alors moins de bande passante de la mémoire externe pour réaliser la même quantité de calculs. Alternativement, il est possible d’effectuer plus de calculs en parallèle pour une bande passante donnée. On note que l’architecture pipelinée réduit aussi la consommation électrique du composant dans lequel est mis en œuvre le circuit de calcul 4, puisqu’une mémoire externe consomme significativement plus que les mémoires internes. La structure de calcul 5 qui vient d’être décrite est donc très avantageuse. La structure nécessite peu de ressources en dehors des « blocs DSP » : les multiplieurs, accumulateurs, multiplexeurs, chaine de décalage, etc. sont déjà inclus dans les blocs DSP. Le besoin en ressources est donc minimal. Comme on l’a vu, chaque composante d’un vecteur appliquée en entrée de la chaîne de calcul 6 est multipliée par chaque donnée du vecteur de poids (comme dans une architecture systolique). Cette structure (2D) permet de minimiser le besoin en bande passante entrante en maximisant la réutilisation des données (contrairement aux structures 3D). L’architecture 2D utilisée présente en effet un excellent facteur multiplicateur de bande passante. Avec une architecture 2D, le facteur de multiplication est de n : en fournissant 16 données et 16 poids, il est possible de faire 256 multiplications. Par comparaison, une architecture de type Tensor Cores présente un facteur de multiplication égal à √n : en fournissant 16 données et 16 poids, il est possible de réaliser seulement 64 multiplications. La bande passante en entrée est donc minimisée, tout comme la bande passante en sortie. On obtient des flux de données entrants homogènes (comme les structures 3D). Ainsi, les sorties se font au même rythme que les entrées. Il n’est pas nécessaire que le vecteur de données appliqué en entrée de chaque chaîne de calcul, et que le vecteur de données appliqué via les deuxièmes blocs mémoire, aient des tailles égales. Dans un FPGA, une contrainte classiquement rencontrée est la dimension des accumulateurs. Ces accumulateurs peuvent ne pas être assez grands pour stocker les résultats d’accumulation pour des masques de grandes dimensions. L’accumulateur de sortie 11, accumulant les poids forts, peut donc être ajouté en fin de chaine de décalage pour réaliser l’accumulation. L’avantage de cette configuration est qu’un seul accumulateur par chaîne de calcul 6 est nécessaire (et pas un par accumulateur), ce qui réduit les ressources nécessaires. La taille des accumulateurs parallélisés dans la chaine pourrait se limiter à : nb bit opérande A + nb bit opérande B + arrondi.sup (log2(L)), où A est le vecteur appliqué via le premier module mémoire 17 et B est le vecteur appliqué via les deuxièmes modules mémoires 18, et où L est la longueur de la chaîne de calcul 6, c’est-à-dire le nombre de blocs de calcul 7 par chaîne 6 (égal à M). Ceci présente un avantage aussi pour un ASIC, où les dimensions sont ajustables. A l’inverse, si les accumulateurs des blocs de calcul sont suffisamment grands ou si l’on cherche à minimiser leur taille, il est possible d’exploiter au maximum les accumulateurs de la chaine de multiplieurs-accumulateurs en réinjectant les calculs en fin de chaine à l’entrée de la chaine. Ceci supposant un pilotage et une organisation des données et poids adaptés. Avantageusement, pour maximiser l’efficacité (le rendement) de la structure, on respecte dans le mode de réalisation de la un critère de dimensionnement selon lequel : N masque = K.M, où N masque est la taille d’un masque, K est un entier positif et M est la largeur de la structure de calcul 5 (c’est-à-dire le nombre de blocs de calcul 7 par chaîne de calcul 6). La taille d’un masque est égale au produit du nombre de lignes par le nombre de colonnes d’un masque en 2D, multiplié par le nombre de canaux du masque. Il est aussi avantageux d’avoir : C out ≥ M, où C out est le nombre de canaux du tenseur de sortie. En effet, comme une donnée en entrée est multipliée M fois, il faut donc contribuer à M résultats. Il faut aussi que le nombre de pixels du tenseur de sortie soit un multiple du nombre de lignes de l’architecture matricielle de la structure de calcul. Comme la sortie est disponible uniquement en fin de chaîne, il convient d’introduire une « périodicité » dans les calculs. On décrit maintenant, en référence à la , un autre mode de réalisation de l’invention. Ce mode de réalisation permet de lever la contrainte qui vient d’être évoquée. Chaque chaîne de calcul 106 du circuit de calcul 104 comprend à nouveau une pluralité de blocs de calcul 107 comprenant un bloc d’entrée 107a, un bloc de sortie 107b et des blocs intermédiaires 107c. Chaque bloc de calcul 107 comprend un premier multiplexeur 108, un multiplieur 109 comprenant une première entrée reliée à une sortie S du premier multiplexeur 108, et un accumulateur 110 ayant une première entrée reliée à une sortie du multiplieur 109. Les premières entrées des premiers multiplexeurs 108 sont reliées entre elles et les deuxièmes entrées des premiers multiplexeurs 108 sont reliées entre elles. Le circuit de calcul comprend à nouveau des blocs de mémoire vive primaires 117 (RAM interne) et des blocs de mémoire vive secondaires 118 (RAM interne). Les blocs 117 et les blocs 118 sont des mémoires internes au FPGA et sont reliés à la source 116 (mémoire externe au FPGA). La chaîne de calcul 106 comprend optionnellement (cela dépend de la taille des accumulateurs et de la taille des masques) un accumulateur de sortie 111 ayant une première entrée reliée à la sortie de l’accumulateur 110 du bloc de sortie 107b. La chaîne de calcul 106 comprend aussi un premier buffer 112 relié à la première entrée E1 du premier multiplexeur 108 du bloc d’entrée 107a, un deuxième buffer 114 relié à la deuxième entrée du premier multiplexeur 108 du bloc d’entrée 107a, et un troisième buffer 115 ayant une entrée reliée à une sortie de l’accumulateur de sortie 111 et une sortie reliée à une deuxième entrée de l’accumulateur de sortie 111. Cette fois, cependant, la sortie S de chaque accumulateur 110 n’est pas reliée à l’accumulateur du bloc suivant ; le décalage physique d’un accumulateur à l’autre est donc supprimé. L’accumulateur 110 n’a ici qu’une entrée. Chaque nouvelle valeur en entrée est additionnée à la valeur stockée en interne de l’accumulateur. A chaque cycle d’horloge, le bloc de calcul 107 additionne donc le résultat de la multiplication réalisée par ledit bloc de calcul 107 avec la valeur accumulée au cycle d’horloge précédent par l’accumulateur 110 dudit bloc de calcul 107. On note qu’il serait possible de mettre en œuvre le bloc 110 avec un additionneur comprenant deux entrées. L’une de ces deux entrées est alors reliée à la sortie du multiplieur 109, et l’autre de ces deux entrées est reliée à la sortie dudit additionneur. Le rebouclage de la sortie de l’additionneur sur une de ses entrées réalise un accumulateur. Chaque bloc de calcul 107 comporte en plus, pour mettre en œuvre cette configuration, un étage de bascule séquencé par une horloge. La chaîne de calcul 106 comprend cette fois un multiplexeur de sortie 113. Pour chaque bloc de calcul 107, la sortie S de l’accumulateur 110 dudit bloc de calcul 107 est reliée à une entrée distincte du multiplexeur de sortie 113. La sortie du multiplexeur de sortie 113 est reliée à la première entrée de l’accumulateur de sortie 111. Le multiplexeur de sortie 113 acquiert donc en entrées toutes les sorties des accumulateurs 110 et en sélectionne une. Le multiplexeur de sortie 113 réalise une sélection qui remplace le décalage physique des résultats de calcul des blocs de calcul 7. On note que, dans les deux cas décrits plus tôt (bloc 110 réalisé par un accumulateur ou par un additionneur), il convient d’initialiser la valeur résidente dans le bloc 110 lorsque la valeur du bloc 110 est lue par le multiplexeur de sortie 113. Dans ce deuxième mode de réalisation, il n’est pas nécessaire de respecter le critère de dimensionnement évoqué plus tôt pour optimiser le rendement. Pour obtenir un rendement maximum, il faut à nouveau que le nombre de pixels du tenseur de sortie soit un multiple du nombre de lignes de l’architecture matricielle de la structure de calcul. Il faut aussi que la taille du masque par sous-pixel de sortie soit supérieure ou égale à M. Il faut que chaque entrée contribue au minimum à M multiplications en parallèle, et donc il faut qu’une donnée entrante contribue à M sorties. Le nombre de sorties auquel l’entrée contribue dépend du nombre de canaux par pixel de sortie et de la taille de chaque masque. Sur un masque 3x3, une donnée entrante contribue à 9 pixels de sorties (x le nombre de canaux par sortie). Cela dépend aussi du stride (nombre de pixels par lesquels le masque se déplace après chaque opération), des groupes, etc. Il faut également que le nombre de canaux de sortie soit supérieur ou égal à M. En effet, en ayant un seul multiplexeur de sortie, il ne peut y avoir qu’un calcul qui se termine par cycle, pour pouvoir l’extraire. On peut donc avoir un rendement élevé tout en utilisant la même structure de calcul pour plusieurs couches. Avec le multiplexeur de sortie 113, le décalage physique des résultats de calcul dans la chaîne n’est plus nécessaire, car le multiplexeur de sortie 113 permet de sélectionner n’importe quel accumulateur 110 pour la sortie. Il est par contre toujours nécessaire de démarrer les calculs de manière décalée pour être en mesure de n’avoir qu’un résultat par cycle. On décrit maintenant, en référence à la , un autre mode de réalisation de l’invention. Chaque chaîne de calcul 206 du circuit de calcul 204 comprend à nouveau une pluralité de blocs de calcul 207 comprenant un bloc d’entrée 207a, un bloc de sortie 207b et des blocs intermédiaires 207c. Chaque bloc de calcul 207 comprend un premier multiplexeur 208 comprenant une première entrée E1, une deuxième entrée E2 et une sortie S, et un deuxième multiplexeur 208’ comprenant une première entrée E1, une deuxième entrée E2 et une sortie S. Chaque bloc de calcul 207 comprend de plus un multiplieur 209 comprenant une première entrée reliée à la sortie S du premier multiplexeur 208, et un accumulateur 210 ayant une première entrée reliée à une sortie du multiplieur 109 et une deuxième entrée reliée à la sortie S du deuxième multiplexeur 208’. Les premières entrées E1 des premiers multiplexeurs 208 des blocs de calcul 207 de la chaîne de calcul 206 sont reliées entre elles, et les deuxièmes entrées E2 des premiers multiplexeurs 208 des blocs de calcul 207 de la chaîne de calcul 206 sont reliées entre elles. La sortie de l’accumulateur 210 de chaque bloc de calcul 207 est reliée à la deuxième entrée E2 du deuxième multiplexeur 208’ dudit bloc de calcul, mais aussi à la première entrée E1 du deuxième multiplexeur 208’ du bloc de calcul 207 suivant dans la chaîne de calcul 206. La sortie de l’accumulateur 210 du bloc de sortie 207b est reliée à la première entrée E1 du deuxième multiplexeur 208’ du bloc d’entrée 207a. Le circuit de calcul comprend à nouveau des blocs de mémoire vive primaires 217 (RAM interne) et des blocs de mémoire vive secondaires 218 (RAM interne, par lesquels sont introduites les données primaires et secondaires provenant de la source 216. La chaîne de calcul 206 comprend optionnellement (cela dépend de la taille des accumulateurs et de la taille des masques) un accumulateur de sortie 211 ayant une première entrée reliée à la sortie de l’accumulateur 210 du bloc de sortie 207b. La chaîne de calcul 206 comprend aussi un premier buffer 212 relié à la première entrée E1 du multiplexeur 208 du bloc d’entrée 207a, un deuxième buffer 214 relié à la deuxième entrée du multiplexeur 208 du bloc d’entrée 207a, et un troisième buffer 215 ayant une entrée reliée à une sortie de l’accumulateur de sortie 211 et une sortie reliée à une deuxième entrée de l’accumulateur de sortie 211. Cette architecture, avec deux multiplexeurs 208, 208’ dans chaque bloc de calcul 207, présente un certain nombre d’avantages. Elle permet de gérer efficacement plus de géométries de masque et, en particulier, les convolutions depthwise (ou des calculs dans lesquels le masque est petit). Elle simplifie l’organisation des opérandes (en particulier les poids). Elle est « gratuite » (en matière de ressources) sur un FPGA Xilinx, car le rebouclage est supporté nativement pas le bloc DSP, via paramétrage dynamique. Elle est compatible des autres variantes déjà décrites, et donc permet d’adapter le séquencement des calculs aux caractéristiques du masque, sans modifier la structure. On voit sur la la représentation du rebouclage en interne d’un bloc DSP. Le PCIN (référence 23) correspond à l’entrée du bloc DSP précédent. Le trait en gras 24 correspond au rebouclage. Le Z (référence 25) est le deuxième multiplexeur 208’. Les modes de réalisation de la structure de calcul 6,106 et 206 qui viennent d’être décrits sont également compatibles en option d’un pruning et, en particulier, d’un pruning structuré (par exemple 2 poids non nuls parmi 4) – et ce, de manière efficace dans un FPGA et très efficace dans un ASIC. Le pruning est une méthode consistant à supprimer des connexions de poids dans un réseau pour augmenter la vitesse d’inférence et réduire la taille de stockage du modèle. Ce pruning est réalisé lors de l’entrainement. Dans le cas de la structure 6, pour rendre ladite structure de calcul compatible avec le pruning , chaque bloc de calcul comprend un multiplexeur additionnel ayant une sortie reliée à la deuxième entrée de l’accumulateur 10 dudit bloc de calcul. Le but est de ne pas faire la multiplication par 0, mais d’occuper quand même le multiplieur. Mais, l’entrée est la suivante, car utile aux autres multiplications. L’idée est donc de faire la multiplication pour le cout suivant, c’est-à-dire en utilisant non pas l’accumulation précédente, mais l’accumulation entre avant. Cela suppose aussi que les 0 des poids sont supprimés (ce qui peut être fait en pré-traitement, nécessitant de la mémoire supplémentaire (pour stocker la position des 0 et des sauts) ou à la volée, moyennant des ressources et une bande passante plus élevée). Dans le cas de la structure 106, pour rendre ladite structure de calcul compatible avec le pruning , la sortie reste localement dans l’accumulateur (et on ne peut pas la déplacer car on écraserait une autre donnée utile). Il faut donc fournir en entrée du multiplieur des données différentes (on suppose aussi que les poids à 0 ne sont pas fournis à la structure). Il faudrait alors un multiplexeur avant le multiplieur et fournir la donnée suivant au multiplieurs (qui sera ensuite fournie aux autres multiplieurs de la même ligne). Le multiplexeur additionnel a une ou des entrées reliées à un ou des accumulateurs d’un ou de blocs de calcul de la même chaîne de calcul. Pour le pruning, le multiplexeur additionnel de chacun des blocs intermédiaires et du bloc de sortie a des entrées reliées aux sorties des accumulateurs du ou des blocs précédents de la même chaîne de calcul. Les multiplexeurs additionnels permettent de sélectionner un autre résultat d’accumulation de la même chaine de calcul (dont le précédent direct et les autres précédents). La structure de calcul peut également être compatible du 0-skipping . Le multiplexeur additionnel a une ou des entrées reliées à un ou des accumulateurs d’un ou de blocs de calcul d’une autre chaîne de calcul. On sait qu’en sortie d’une fonction d’activation ReLU, toutes les valeurs négatives sont arrondies à 0. Les sorties des fonctions ReLU sont multipliées par les poids du neurone suivant. Le 0-skipping consiste à « sauter » les multiplications par des valeurs qui valent 0. Cette méthode n’a aucun impact sur la performance de l’algorithme, puisque seuls les calculs inutiles sont « sautés ». Le gain dépend de la proportion de données à 0 et, potentiellement, de leur dispersion spatiale. Le 0-skipping rend plus difficile la parallélisation – mais réduit le besoin de parallélisation. Le 0-skipping est réalisé en positionnant à nouveau, dans chaque bloc de calcul, un multiplexeur additionnel en entrée de la deuxième entrée de l’accumulateur. Le multiplexeur additionnel a cette fois des entrées reliées à un ou des accumulateurs de blocs de calcul d’une autre chaîne de calcul (au-dessus ou au-dessous) ou de la même chaîne de calcul. Ceci implique d’avoir une ou des entrées à 0. Mais, il faut toujours les mêmes poids (car d’autres pixels peuvent en avoir besoin). Donc, si on fait toujours le même nombre de multiplications avec les mêmes poids, mais en sautant des données, il faut calculer des pixels voisins. Il faut donc décaler les calculs d’une ligne à l’autre et mémoriser la ou les accumulations non calculée(s) à ce cycle. On note qu’il convient de prévoir des registres pour mémoriser les résultats d’accumulation qui ne sont pas utilisés dans l’étage suivant, mais qui sont utilisés dans un étage ultérieur. Les mises en œuvre du pruning et du 0-skipping peuvent se cumuler, ce qui est particulièrement avantageux, car aucune structure de l’état de l’art ne peut supporter simultanément et efficacement le pruning et le 0-skipping . La structure de calcul, via un pilotage adapté et des étages d’additions supplémentaires, est également compatible de la transformée de Winograd , qui permet de réduire le nombre de multiplications à réaliser pour une convolution de masque 3x3 ou supérieur. On sait que la multiplication nécessite plus de ressources qu’une addition dans une architecture matérielle ( hardware ). L’intérêt de la transformée de Winograd est qu’elle permet de réduire le nombre de multiplications et donc les ressources nécessaires. Le principe de la transformée de Winograd est de factoriser des multiplications pour des positions voisines. Cependant, la transformée de Winograd augmente le nombre d’additions, car elle nécessite de réaliser des additions avant et après les multiplications. Ainsi, pour une convolution 3x3 et un voisinage 2x2, en convolution classique, 9 multiplications et 8 additions sont nécessaires pour chaque pixel calculé, et donc 36 multiplications et 32 additions. En utilisant la transformée de Winograd, 16 multiplications et 56 additions sont nécessaire. La transformée de Winograd réduit donc d’un facteur égal à 2,25 le nombre de multiplications à réaliser, mais elle augmente d’un facteur égal 1,75 le nombre d’additions. La structure est également compatible de taille de masque quelconque ou de taille de données quelconque. De nombreuses variantes sont envisageables. Il serait possible d’utiliser la structure de multiplexage des entrées en colonne également, permettant plus de cas d’utilisations. Dans la structure de calcul, il serait possible d’inverser les lignes et les colonnes (multiplexage et décalage des résultats intermédiaires sur les colonnes et sur les lignes). Pour une convolution d’un modèle d’apprentissage profond, les données sont typiquement fournies par le côté et les poids par le haut. Il est donc possible d’inverser les données et les poids. Ceci peut présenter un intérêt en fonction des dimensions des données. De manière préférentielle, les informations alimentées par le haut proviennent de la mémoire interne et les données provenant du côté sont diffusées en continu depuis la mémoire externe ou depuis une autre structure (similaire ou pas). Si les poids sont plus volumineux que les données, il est alors plus intéressant de stocker les données en mémoire interne et de diffuser en continu les poids depuis la mémoire externe, ce qui permet de minimiser le temps de traitement global. Il serait aussi possible de positionner un multiplexeur sur chacune des deux entrées principales. Il est possible d’implémenter le circuit de calcul dans tout type de FPGA. Il est également possible d’utiliser peu ou pas les blocs DSP et de réaliser certaines ou toutes les parties du circuit de calcul avec de la logique FPGA. Il est également possible d’implémenter le circuit de calcul dans un ASIC, qui ne possède pas de structure prédéfinie (comme les blocs DSP). Un plus grand nombre de variantes serait alors possible, permettant d’autres compromis (par exemple augmenter la bande passante de sortie pour minimiser la durée de décalage). A noter que cette variante est également faisable sur FPGA. Ceci consisterait à « segmenter » la chaine de décalage pour créer des sorties supplémentaires, permettant de gérer efficacement d’autres tailles de variables. Il est également possible d’utiliser plus de multiplexeurs de sortie (pour la variante sans décalage), voire de cumuler décalage, sortie fixe en fin de chaîne de calcul, sortie fixe à un point intermédiaire et un ou plusieurs multiplexeurs pour sélectionner d’autres parties de la chaine. Si le circuit de calcul est réalisé pour un réseau spécifique, les dimensions de chaque structure (hauteur, largeur, taille des multiplieurs et des accumulateurs) peuvent être ajustées pour maximiser le rendement, ou pour maximiser la performance ou minimiser les ressources utilisées, ou pour obtenir un compromis performance/ressources, ou selon n’importe quel critère d’optimisation. Bien entendu, l’invention n’est pas limitée au mode de réalisation décrit mais englobe toute variante entrant dans le champ de l’invention tel que défini par les revendications. Circuit de calcul (4 ; 104 ; 204) comportant au moins une chaîne de calcul (6 ; 106 ; 206) comprenant une pluralité de blocs de calcul (7 ; 107 ; 207) comportant chacun un multiplieur (9 ; 109 ; 209) comprenant une première entrée et une deuxième entrée, et un accumulateur (10 ; 110 ; 210) comprenant une première entrée reliée à une sortie du multiplieur, le circuit de calcul étant agencé pour, de manière cadencée par des cycles d’horloge, appliquer sur les premières entrées des multiplieurs des blocs de calcul de ladite chaîne de calcul une succession de données primaires formant au moins un vecteur primaire, et appliquer sur les deuxièmes entrées des multiplieurs des blocs de calcul de ladite chaîne de calcul une succession de séries de données secondaires formant des vecteurs secondaires, chaque bloc de calcul de ladite chaîne de calcul étant agencé pour, à chaque cycle d’horloge, additionner un résultat d’une multiplication réalisée par ledit bloc de calcul avec une valeur accumulée au cycle d’horloge précédent par l’accumulateur dudit bloc de calcul ou d’un autre bloc de calcul de ladite chaîne de calcul, la chaîne de calcul étant ainsi agencée pour produire successivement des résultats de multiplications du au moins un vecteur primaire par chaque vecteur secondaire. Circuit de calcul selon la revendication 1, comprenant un nombre N de chaînes de calcul (6 ; 106 ; 206) formant des lignes d’une structure matricielle, chaque chaîne de calcul comprenant un nombre M de blocs de calcul (7 ; 107 ; 207), les deuxièmes entrées des multiplieurs des blocs de calcul d’une même colonne de ladite structure matricielle étant connectées entre elles. Circuit de calcul selon l’une des revendications précédentes, chaque bloc de calcul de chaque chaîne de calcul comportant un premier multiplexeur (8 ; 108 ; 208) comprenant une première entrée et une deuxième entrée, la première entrée du multiplieur dudit bloc de calcul étant reliée à une sortie dudit premier multiplexeur, les premières entrées des premiers multiplexeurs (8 ; 108 ; 208) des blocs de calcul de ladite chaîne de calcul étant reliées entre elles et les deuxièmes entrées des premiers multiplexeurs (8 ; 108 ; 208) des blocs de calcul de ladite chaîne de calcul étant reliées entre elles, le circuit de calcul étant agencé pour appliquer sur les premières entrées desdits premiers multiplexeurs une succession de premières données primaires formant un premier vecteur primaire, appliquer sur les deuxièmes entrées desdits premiers multiplexeurs (8 ; 108 ; 208) une succession de deuxièmes données primaires formant un deuxième vecteur primaire, la chaîne de calcul étant agencée pour produire successivement et en série des résultats de multiplications du premier vecteur primaire par chaque vecteur secondaire puis du deuxième vecteur primaire par chaque vecteur secondaire. Circuit de calcul selon l’une des revendications précédentes, chaque bloc de calcul (207) de chaque chaîne de calcul (206) comprenant un deuxième multiplexeur (208’) agencé de sorte que : - une sortie dudit deuxième multiplexeur est reliée à une deuxième entrée de l’accumulateur (210) dudit bloc de calcul ; - une sortie dudit accumulateur étant reliée à une première entrée dudit deuxième multiplexeur ; - une sortie dudit accumulateur étant relié à une première entrée d’un bloc suivant de ladite chaîne de calcul. Circuit de calcul selon l’une des revendications précédentes, dans lequel les blocs de calcul (7) de chaque chaîne de calcul comprennent un bloc d’entrée (7a), un bloc de sortie (7b) et des blocs intermédiaires (7c) positionnés entre le bloc d’entrée et le bloc de sortie, la chaîne de calcul (6) étant agencée de sorte qu’une sortie de l’accumulateur (10) de chacun des bloc d’entrée (7a) et blocs intermédiaires (7c) est reliée à une deuxième entrée de l’accumulateur d’un bloc suivant de ladite chaîne de calcul. Circuit de calcul selon la revendication 5, dans lequel la sortie de l’accumulateur du bloc de sortie (7b) est reliée à une deuxième entrée de l’accumulateur du bloc d’entrée (7a). Circuit de calcul selon l’une des revendications précédentes, dans lequel chaque chaîne de calcul comprend un multiplexeur de sortie (113), ladite chaîne de calcul étant agencée de sorte que, pour chaque bloc de calcul (107), la sortie de l’accumulateur (110) dudit bloc de calcul est reliée à une entrée distincte du multiplexeur de sortie (113). Circuit de calcul selon l’une des revendications précédentes, dans lequel chaque chaîne de calcul (6 ; 206) comprend en outre un accumulateur de sortie (11 ; 211) ayant une première entrée reliée à la sortie de l’accumulateur (10 ; 210) d’un bloc de sortie (7b ; 207b) de ladite chaîne de calcul. Circuit de calcul selon la revendication 7, dans lequel chaque chaîne de calcul comprend en outre un accumulateur de sortie (111) ayant une première entrée reliée à la sortie du multiplexeur de sortie (113) de ladite chaîne de calcul. Circuit de calcul selon la revendication 3, comprenant en outre un premier buffer (12 ; 112 ; 212) relié à la première entrée du premier multiplexeur (8 ; 108 ; 208) d’un bloc d’entrée (7a ; 107a ; 207a) de la chaîne de calcul, et un deuxième buffer (14 ; 114 ; 214) relié à la deuxième entrée du premier multiplexeur (8 ; 108 ; 207) du bloc d’entrée de la chaîne de calcul. Circuit de calcul selon l’une des revendications 8 ou 9, comprenant en outre un troisième buffer (15 ; 115 ; 215) ayant une entrée reliée à une sortie de l’accumulateur de sortie (11 ; 111 ; 211) et une sortie reliée à une deuxième entrée de l’accumulateur de sortie. Circuit de calcul selon l’une des revendications précédentes, comprenant un bloc de mémoire vive primaire (17 ; 117 ; 217) pour chaque chaîne de calcul, et une pluralité de blocs de mémoire vive secondaires (18 ; 118 ; 218), les données primaires et les données secondaires étant appliquées pour chaque chaîne de calcul respectivement via le bloc de mémoire vive primaire associé à ladite chaîne de calcul et via les blocs de mémoire vive secondaires, les blocs de mémoire vive primaires et les blocs de mémoire vive secondaires permettant de fournir aux chaînes de calcul plusieurs fois des mêmes données primaires ou secondaires sans avoir besoin d’accéder à chaque fois à une ou des sources de données (16 ; 116 ; 216) desquelles proviennent les données primaires et les données secondaires. Circuit de calcul selon la revendication 2 ou la revendication 5, le circuit de calcul étant configuré pour effectuer un produit de convolution d’un tenseur d’entrée par un masque de taille N masque pour obtenir un tenseur de sortie, le circuit de calcul étant tel que : N masque = K.M, où K est un entier positif. Circuit de calcul selon la revendication 3, le circuit de calcul étant agencé pour : - appliquer les séries de données secondaires selon une séquence cyclique prédéfinie ; - démarrer l’application des premières données primaires sur les premières entrées des premiers multiplexeurs (8 ; 108) puis, après un nombre prédéfini de cycles d’horloge, démarrer l’application des deuxièmes données primaires sur les deuxièmes entrées des premiers multiplexeurs (8 ; 108) ; - piloter les premiers multiplexeurs de sorte que la chaîne de calcul (6 ; 106), simultanément, termine une multiplication du premier vecteur primaire par chacun des vecteurs secondaires et débute une multiplication du deuxième vecteur primaire par chacun des vecteurs secondaires. Circuit de calcul selon la revendication 14, les vecteurs secondaires formant une matrice, la séquence cyclique prédéfinie comportant des cycles comprenant chacun une première phase au cours de laquelle les séries de données secondaires comprennent un nombre croissant de composantes de lignes ou de colonnes successives de la matrice, une deuxième phase au cours de laquelle les séries de données secondaires comprennent un nombre constant de composantes de lignes ou de colonnes successives de la matrice, et une troisième phase au cours de laquelle les séries de données secondaires comprennent un nombre décroissant de composantes de lignes ou de colonnes successives de la matrice. Circuit de calcul selon l’une des revendications précédentes, dans lequel le circuit de calcul comprend plusieurs chaînes de calcul et un multiplexeur additionnel ayant une ou des entrées reliées à un ou des accumulateurs d’un ou de blocs de calcul de la même chaîne de calcul et/ou d’une autre chaîne de calcul. Circuit de calcul selon l’une des revendications précédentes, comprenant une pluralité de structures de calcul (5a, 5b, 5c) comprenant chacune une pluralité de chaînes de calcul (6), les structures de calcul étant arrangées selon une architecture pipeline. Circuit de calcul selon la revendication 17, chaque structure de calcul étant agencée pour effectuer des produits de convolution pour une couche de convolution distincte d’un modèle de réseau de neurones. Composant électronique dans lequel est réalisé le circuit de calcul selon l’une des revendications précédentes. Composant électronique selon la revendication 19, le composant électronique étant un FPGA. Composant électronique selon la revendication 20, le FPGA comprenant des blocs DSP, chaque bloc de calcul étant réalisé dans un bloc DSP. Composant électronique selon la revendication 21, le circuit de calcul comprenant au moins une structure de calcul présentant une architecture matricielle comprenant une pluralité de chaînes de calcul formant des lignes de l’architecture matricielle, le circuit de calcul comprenant des blocs DSP dans chacun desquels sont réalisés deux blocs de calcul de deux lignes successives. Composant électronique selon la revendication 19, le composant électronique étant un ASIC.