C# and Large Array >4GB

Gianluca G 1 Reputation point
2022-07-15T07:42:58.067+00:00

I'm working with C# in VS2022 Enviroment.
I have a program that uses large array and pass these array to mkl dll.
It seams debugging that C part receive a wrong data after 4GB block.

Any one have faced this kind of problem?

It seams C# cannot alloc a block of memory more than 4G contiguously.
Or is it possible that the parameter declaration in C# is not properly configured?

gcAllowVeryLargeObjects = true was alredy configured, and also that the program is compiled for x64 platform.

This is how variables are declared in C#:

    int MAX_SIZE = 16385; //limit 16385  
    Complex[,] A = new Complex[MAX_SIZE, MAX_SIZE];  
    Complex[] b = new Complex[MAX_SIZE];  

The arrays are populated than passed to the dll.

This is the dll declaration in C#:

  [DllImport("mkl_rt.2.dll", ExactSpelling = true, SetLastError = false, CallingConvention = CallingConvention.Cdecl)]  
        internal static extern int LAPACKE_zgesvxx(  
            int matrix_layout,  
            char fact,  
            char trans,  
            Int64 n,  
            Int64 nrhs,  
            [In, Out] Complex* A,  
            Int64 lda,  
            [In, Out] Complex* af,  
            Int64 ldaf,  
            Int64[] ipiv,  
            ref char equed,  
            [In, Out] double* r,  
            [In, Out] double* c,  
            [In, Out] Complex* B,  
            Int64 ldb,  
            [In, Out] Complex* x,  
            Int64 ldx,  
            ref double rcond,  
            ref double rpvgrw,  
            [In, Out] double[] berr,  
            Int64 n_err_bnds,  
            [In, Out] double[] err_bnds_norm,  
            [In, Out] double[] err_bnds_comp,  
            Int64 nparams,  
            [In, Out] double[] parameters  
        );  

Thank you

Developer technologies C#
{count} votes

2 answers

Sort by: Most helpful
  1. Bruce (SqlWork.com) 77,686 Reputation points Volunteer Moderator
    2022-07-18T18:29:38.83+00:00

    from the docs you have two restrictions, max array dimension size, and default allocation:

    The array size is limited to a total of 4 billion elements, and to a maximum index of 0X7FEFFFFF in any given dimension (0X7FFFFFC7 for byte arrays and arrays of single-byte structures).

    .NET Framework only: By default, the maximum size of an Array is 2 gigabytes (GB). In a 64-bit environment, you can avoid the size restriction by setting the enabled attribute of the gcAllowVeryLargeObjects configuration element to true in the run-time environment.

    0 comments No comments

  2. Gianluca G 1 Reputation point
    2022-07-19T07:04:15.79+00:00

    Dear Bruce, this is what I read.

    By the way, I resolved the problem making many tries and I've discovered this:

    what I've understandood is that C# manages array 2D (n dimension?) contiguosly if the size is less than 4GB (because it works).
    Than, if the size is upper, this is not more valid, each dimension has a potential different allocated block (strange).
    In conclusion the 2D array pointer is not reliable.

    Infact, when I've tested the values C# side the values were correct, and this let me think that all pointers were correct too.

    the solution was replacing the 2D array with a 1D Array

    Before

    Complex[,] A = new Complex[MAX_SIZE, MAX_SIZE];  
    

    After

    Complex[,] A = new Complex[MAX_SIZE * MAX_SIZE];  
    

    consider that the pointer is passed to the function

    fixed (Complex* ptr_a = &A[0])  
    
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.