c++arrayspointersmetalc++-attributes

No matching function to call 'createMatrix'


What I'm trying to do

I'm trying to convert a buffer of type [Int] to [[Int]]. Since arrays are not super easy to return in C, I'm creating a new empty array and passing the pointer into a void function that is supposed to fill the address space with Integers from the buffer.

Afterwards, the matrices are supposed to get added and the result written into a result buffer.

The problem

For some reason, it can't find my function. I'm kind of new to c++ so excuse me when it's something simple I'm overlooking here. The function is not part of a class. So technically it should be in the same namespace?

#include <metal_stdlib>
using namespace metal;



void createMatrix(device int **arr, int count, int buff[]) {
    for(int i = 0; i < count; i++)
     for(int j = 0; j < count; j++)
        arr[j][i] = buff[i + j];
}


kernel void addition_compute_function(constant int *arr1        [[ buffer(0) ]],
                                      constant int *arr2        [[ buffer(1) ]],
                                      device   int *resultArray [[ buffer(2) ]],
                                               uint   index [[ thread_position_in_grid ]]) {



    int array1[6][6] = {{0}};
    createMatrix(**array1, 6, *arr1); // ERROR: No matching function for call to 'createMatrix'
    
    int array2[6][6] = {{0}};
    createMatrix(**array2, 6, *arr2); // ERROR: No matching function for call to 'createMatrix'

    for (int i = 1; i <= 6; i++){
            resultArray[i][index] = array1[i][index] + array2[i][index]; // ERROR: Subscripted value is not an array, pointer, or vector
    }

}

What I tried

Most questions regarding this error are concerning methods of a class getting called after an object is initialized. This isn't the case here, so no dice thus far in researching the problem.

Edit, incorporated feedback

#include <metal_stdlib>
using namespace metal;



void createMatrix(device int (*arr)[6], int count,constant int* buff) {
    for(int i = 0; i < count; i++)
     for(int j = 0; j < count; j++)
        arr[j][i] = buff[i + j];
}


kernel void addition_compute_function(constant int *arr1        [[ buffer(0) ]],
                                      constant int *arr2        [[ buffer(1) ]],
                                      device   int *resultArray [[ buffer(2) ]],
                                               uint   index [[ thread_position_in_grid ]]) {



    int array1[6][6] = {{0}};
    createMatrix(array1, 6, arr1); //ERROR: No matching function for call to 'createMatrix'
    
    int array2[6][6] = {{0}};
    createMatrix(array2, 6, arr2); //ERROR: No matching function for call to 'createMatrix'

    int tempResultArray[6][6] = {{0}};
    
    // I want to do some stuff here I find the 2d array form more convientient to work with, therefore the back and forth
    for (int i = 1; i <= 6; i++){
            tempResultArray[i][index] = array1[i][index] + array2[i][index];
    }
    
    for (int i = 1; i <= 6; i++){
        for (int j = 1; j <= 6; j++){
            resultArray[i+j] = tempResultArray[i][j];
            
    }
}

Edit2

I gave up, nothing worked. I can't find the reason the function was is not recognized. I don't even know if it's the way I'm calling the function/populating the parameters, or if the namespace is wrong. Documentation for this behavior is lacking. Ended up hardcoding the function to create a 2d array from 1d array and vice versa.


Solution

  • Any variable that is a pointer or reference must be declared with one of the address space attributes.

    This is the correct implementation of your function:

    void createMatrix(device int (*arr)[6][6], int count, constant int* buff) {
        for(int i = 0; i < count; i++)
            for(int j = 0; j < count; j++)
                (*arr)[j][i] = buff[i + j];
    }
    

    Kernel:

    device int (*array1)[6][6] = {{0}};
    createMatrix(array1, 6, arr1);