Matrix inversion in OpenCL

前端 未结 6 1200
终归单人心
终归单人心 2021-02-06 06:39

I am trying to accelerate some computations using OpenCL and part of the algorithm consists of inverting a matrix. Is there any open-source library or freely available code to c

6条回答
  •  鱼传尺愫
    2021-02-06 07:16

    I make calculus up to 2k x 2k at CPU using multithread using eigen lib, so it is now 3.5-3.65 times faster (depends of matrix size) than using one thread. I used an Intel Xeon 3.5Ghz E5-1620 v3 processor and 16Gb ram. (Unfortunately I deleted the old version to add exact values, but if has some priority I could rewrite the sw)

    This is my matrix inverse algorithm I used to compare with. (It is correct as I stated making a lot of tests again excel result):

    /*
    Uses 2D arrays.
    Main routines are:
    init_2Dvector() that initializes any 2d vector (can be uchar, char, int, float or double)
    multiply_2Dvector()
    inverse()
    */
    
    #include
    #include 
    #include 
    #include 
    
    using namespace std;
    
    /*
    void print_2Dvector(vector >& vec)
    {
        size_t xmax, ymax;
        ymax = vec.size();
        xmax = vec[0].size(); 
    
        int x, y;
        for (y = 0; y < ymax; y++)
        {
            for (x = 0; x < xmax; x++)
                cout << vec[y][x] << " \t";
            cout << endl;
        }
    }*/
    
    void print_2Dvector(vector >& vec,char *format="%lg \t")
    {
        size_t xmax, ymax;
        ymax = vec.size();
        xmax = vec[0].size();
    
        int x, y;
        for (y = 0; y < ymax; y++)
        {
            {
                for (x = 0; x < xmax; x++)
                    printf(format, vec[y][x]);
            }
            cout << endl;
        }
    }
    
    //Resizes to y_dim,x_dim any kind of 2d array:
    template
    void init_2Dvector(vector >& vec, size_t y_dim, size_t x_dim)
    {
        vec.resize(y_dim);
        for (size_t i = 0; i < vec.size(); i++)
            vec[i].resize(x_dim);
    }
    //Returns vec1*vec2. vec1 and 2 are not touch
    vector< vector > multiply_2Dvector(vector< vector > vec1, vector< vector > vec2)
    {
        size_t xmax, ymax;
        ymax = vec1.size();   
        xmax = vec1[0].size();
        vector< vector > vec3;
        if ((ymax != vec2[0].size()) || (xmax != vec2.size()))
        {
            cout << "ERROR on dim2_multiply() dimensions of vec2 not corresponding with vec1 ones" << endl; getchar(); return{};//returns a null
        }
        init_2Dvector(vec3, ymax, ymax);
        cout << "dimensions of vec3=" << vec3.size() << " x " << vec3[0].size() << endl;
        double xx;
        for (int y = 0; y < ymax; y++)
            for (int x = 0; x < ymax; x++)
            {
                xx = 0.0;
                for (int t = 0; t < xmax; t++)
                    xx += vec1[y][t] * vec2[t][x];
                vec3[y][x] = xx;
            }
        return vec3;//ok
    }
    
    //returns inverse of x2, x2 is not modified
    vector< vector > inverse(vector< vector > x)
    {
        if (x.size() != x[0].size())
        {
            cout << "ERROR on inverse() not square array" << endl; getchar(); return{};//returns a null
        }
    
        size_t dim = x.size();
        int i, j, ord;
        vector< vector > y(dim,vector(dim));//output
        //init_2Dvector(y, dim, dim);
        //1. Unity array y: 
        for (i = 0; i < dim; i++)
        {
            y[i][i] = 1.0;
            for (j = i+1; j < dim; j++)
            {
                y[i][j]= y[j][i] = 0.0;
            }
        }
    
        double diagon, coef;
        double *ptrx, *ptry, *ptrx2, *ptry2;
        for (ord = 0; ord1e-15) break;
                }
                if (i2 >= dim)
                    return{};//error, returns null
                for (i = 0; i > vec1 = {
            {0,-5,0,7,33,11,-1},
            {72,0,-11,7,9,33,5 },
            {-13,31,-5,15,29,30,24 },
            {-24,9,8,-23,31,-12,4 },
            {-3,-22,4,-24,-5,27,-10 },
            {-10,-21,-16,-32,-11,20,14 },
            {5,30,13,-32,29,-13,-13 }
        };
        vector< vector > vec2;
        vec2 = inverse(vec1);
        vector< vector > vec3;
        vec3 = multiply_2Dvector(vec1, vec2);
    
        cout << "initial array (must be unmodified):" << endl;
        print_2Dvector(vec1);
    
        cout << "Must be diagon array:" << endl;
        print_2Dvector(vec3," %8.3lf");
        cout << endl;
    }
    
    
    void test_6_inverse(int dim)
    {
        vector< vector > vec1(dim, vector(dim));
        for (int i=0;i > vec2;
        double ini, end;
        ini = (double)clock();
        vec2 = inverse(vec1);
        end = (double)clock();
        cout << "Time inverse =" << (end - ini) / CLOCKS_PER_SEC << endl;
        vector< vector > vec3;
        vec3 = multiply_2Dvector(vec1, vec2);
    
        cout << "initial array (must be unmodified):" << endl;
        //print_2Dvector(vec1);
    
        cout << "Must be diagon array:" << endl;
        //print_2Dvector(vec3, " %8.3lf");
        cout << endl;
    }
    
    int main()
    {
        vector< vector > vec1;
        init_2Dvector(vec1, 10, 5);    //size_t ymax = vec1.size(),xmax = vec1[0].size();
        //test_2_dimension_vector();
        //test_one_dimension_vector();
        test_5_inverse();
        test_6_inverse(1300);
        cout << endl << "=== END ===" << endl; getchar(); 
        return 1;
    }
    

提交回复
热议问题