1
votes

définir un tableau de constantes 2D dans une macro C

Je voudrais charger un tableau statique en mémoire, utilisé comme noyau de convolution dans une boucle ultérieure, en C99 et versions ultérieures. J'ai essayé ça:

static const __m128 filter_sse[5][5] = { { _mm_set1_ps(filter[0][0]),
                                         ... },
                                           ... };

GCC 8 se plaint:

error: expected expression before « { » token
 #define filter { {0.00390625f, 0.015625f, 0.0234375f, 0.015625f, 0.00390625f}, \

J'ai trouvé comment charger des vecteurs 1D, mais comment le faire avec 2D ?

Modifier

Le but ultime est de créer un tableau SIMD à partir de celui-ci:

/** This is the outer product of
 * filter[5] = { 1.0f / 16.0f, 4.0f / 16.0f, 6.0f / 16.0f, 4.0f / 16.0f, 1.0f / 16.0f };
 * computed at once, outside of the pixels loops, saving 25 multiplications per pixel
 * */
#define filter[5][5] { {0.00390625f, 0.015625f, 0.0234375f, 0.015625f, 0.00390625f}, \
                       {0.01562500f, 0.062500f, 0.0937500f, 0.062500f, 0.01562500f}, \
                       {0.02343750f, 0.093750f, 0.1406250f, 0.093750f, 0.02343750f}, \
                       {0.01562500f, 0.062500f, 0.0937500f, 0.062500f, 0.01562500f}, \
                       {0.00390625f, 0.015625f, 0.0234375f, 0.015625f, 0.00390625f} }

et l'utilisation d'un static const float filter [5] [5] le fait se plaindre d'essayer de définir une constante avec des valeurs non constantes.


5 commentaires

pourquoi pas simplement const float filter [5] [5] = ... ?


car j'ai besoin d'un autre tableau avec des vecteurs SIMD comme const __m128 filter_sse [i] [j] = {_mm_set1_ps (filter [i] [j])} , et GCC se plaint que j'essaie de définir un const avec non-const si j'utilise juste un const float filter [5] [5]


Il ne peut pas y avoir de tableaux d'expressions interprétatives en C, votre meilleure option serait de placer les valeurs directement dans l'initialiseur de destination. Vous pouvez même y placer les calculs plutôt que les constantes flottantes du résultat.


@ M.M Je ne veux pas mettre le calcul dans les boucles… c'est 25 multiplications inutiles par pixel, ça n'a pas de sens. J'ai besoin de const pour éviter le faux partage dans les boucles parallèles.


@ AurélienPierre le calcul s'effectuera au moment de la compilation


3 Réponses :


1
votes

La réclamation concerne l'opérateur = manquant:

Essayez ceci:

const float ARRAY;
double a = filter[0][0];  //example assignment using #defined array 

Plus tard (par exemple) ... p>

#define ARRAY filter[5][5] = { {0.00390625f, 0.015625f, 0.0234375f, 0.015625f, 0.00390625f},\
                       {0.01562500f, 0.062500f, 0.0937500f, 0.062500f, 0.01562500f},\
                       {0.02343750f, 0.093750f, 0.1406250f, 0.093750f, 0.02343750f},\
                       {0.01562500f, 0.062500f, 0.0937500f, 0.062500f, 0.01562500f},\
                       {0.00390625f, 0.015625f, 0.0234375f, 0.015625f, 0.00390625f} };


7 commentaires

Le symbole = dans une déclaration n'est pas l'opérateur d'affectation


cela a le problème que toutes les valeurs sont déclarées comme float via le f de fin sur chaque valeur. Si vous souhaitez déclarer des valeurs doubles , supprimez le f de fin


@ user3629249 - Merci de l'avoir signalé. J'ai fait une correction.


@ M.M - Je ne trouve rien dans le langage standard C qui fasse référence au symbole = comme autre chose qu'un opérateur affectation . (accordé, je regarde une copie de 11/2010 de l'ISO / CEI 9899: 201x). J'ai desserré le libellé de ma réponse, mais j'aimerais connaître le terme correct utilisé pour faire référence au symbole = utilisé dans une déclaration. Pouvez-vous s'il vous plaît le lier? Merci.


dans la déclaration d'une variable, le réglage de la variable à une certaine valeur est 'initialisation' (qui fonctionne selon des règles légèrement différentes de celles d'une affectation (ultérieure) à cette variable


@ user3629249 - Si vous adressez ma réponse et ma question à M.M , je ne sais pas comment cela répond à la question sur le nom du symbole = . M.M affirme que le symbole = n'est pas appelé opérateur affectation lorsqu'il est utilisé pour l'initialisation. Cependant, que ce soit pour l'attribution de variables ou pour l'initialisation, je ne trouve aucune référence dans le langage C qui utilise un titre différent pour le symbole = que opérateur d'affectation . Peut tu?


@ryyker Je l'appelle "le symbole = ". Si vous regardez 6.5.16 "Opérateurs d'affectation", vous verrez que cette utilisation ne satisfait pas la grammaire de expression-d'affectation (et donc une correspondance d'analyse potentielle avec opérateur-d'affectation sera rétrogradé). Regardez plutôt la syntaxe dans 6.7 "Déclarations", en particulier " déclarateur = initialiseur ". Ce n'est pas du tout un opérateur. (Les opérateurs sont traités sous 6.5 "Expressions"; ils opèrent sur 1, 2 ou 3 expressions pour produire une autre expression; cependant, une déclaration n'est pas une expression)



4
votes

Vous avez laissé le = entre le filtre [5] [5] et le {{.

Et, comme vous l'avez , filter ne peut pas être le nom de la macro car il est suivi par les crochets

Et, vous avez besoin du type (par exemple float ) p>

Voici une version nettoyée:

#define DEFME float filter[5][5] = { \
    {0.00390625f, 0.015625f, 0.0234375f, 0.015625f, 0.00390625f}, \
    {0.01562500f, 0.062500f, 0.0937500f, 0.062500f, 0.01562500f}, \
    {0.02343750f, 0.093750f, 0.1406250f, 0.093750f, 0.02343750f}, \
    {0.01562500f, 0.062500f, 0.0937500f, 0.062500f, 0.01562500f}, \
    {0.00390625f, 0.015625f, 0.0234375f, 0.015625f, 0.00390625f} }

DEFME;

Remarque: Mais pourquoi utiliser une macro pour cela?


0 commentaires

2
votes

Abstraction de son sens

#include <stdio.h>

#define myfilter(name) name[5][5] = { {0.00390625f, 0.015625f, 0.0234375f, 0.015625f, 0.00390625f}, \
                       {0.01562500f, 0.062500f, 0.0937500f, 0.062500f, 0.01562500f}, \
                       {0.02343750f, 0.093750f, 0.1406250f, 0.093750f, 0.02343750f}, \
                       {0.01562500f, 0.062500f, 0.0937500f, 0.062500f, 0.01562500f}, \
                       {0.00390625f, 0.015625f, 0.0234375f, 0.015625f, 0.00390625f} }

int main()
{
    const float myfilter(filter1);
    printf("%f\n", filter1[1][1]);

    return 0;
}


0 commentaires