0

I have a very straightforward function that counts how many inner entries of an N by N 2D matrix (represented by a pointer arr) is below a certain threshold, and updates a counter below_threshold that is passed by reference:

void count(float *arr, const int N, const float threshold, int &below_threshold) {
    below_threshold = 0;  // make sure it is reset
    bool comparison;
    float temp;
    
    #pragma omp parallel for shared(arr, N, threshold) private(temp, comparison) reduction(+:below_threshold)
    for (int i = 1; i < N-1; i++)  // count only the inner N-2 rows
    {
        for (int j = 1; j < N-1; j++)  // count only the inner N-2 columns
        {
            temp = *(arr + i*N + j);
            comparison = (temp < threshold);
            below_threshold += comparison;
        }
    }
}

When I do not use OpenMP, it runs fine (thus, the allocation and initialization were done correctly already).

When I use OpenMP with an N that is less than around 40000, it runs fine.

However, once I start using a larger N with OpenMP, it keeps giving me a segmentation fault (I am currently testing with N = 50000 and would like to eventually get it up to ~100000).

Is there something wrong with this at a software level?


P.S. The allocation was done dynamically ( float *arr = new float [N*N] ), and here is the code used to randomly initialize the entire matrix, which didn't have any issues with OpenMP with large N:

void initialize(float *arr, const int N)
{
    #pragma omp parallel for
    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < N; j++)
        {
            *(arr + i*N + j) = static_cast <float> (rand()) / static_cast <float> (RAND_MAX);
        }
    }

}

UPDATE:

I have tried changing i, j, and N to long long int, and it still has not fixed my segmentation fault. If this was the issue, why has it already worked without OpenMP? It is only once I add #pragma omp ... that it fails.

5Pack
  • 313
  • 1
  • 9
  • FYI: [How to generate random numbers in parallel?](https://stackoverflow.com/q/4287531/10107454). – paleonix Mar 02 '22 at 14:39
  • 1
    In good C++, please don't use `new`? Use `std::vector` or `std:array` instead. That might even have caught this error because may very well be allocating with a negative size. PS C++ also has a better random number generator than what you're using, which additionally can be used thread-safe. – Victor Eijkhout Mar 02 '22 at 14:56
  • @VictorEijkhout Is std::vector and std::array guaranteed to be memory contiguous? – 5Pack Mar 02 '22 at 15:14
  • Yes, contiguous, if you don't make a `vector>`. An `array>` *is* going to be contiguous. I think. – Victor Eijkhout Mar 02 '22 at 15:18
  • Changing it to long int doesn't work... – 5Pack Mar 02 '22 at 16:44
  • As mentioned in another comment, `std::ptrdiff_t` from `#include ` is more consistent than `long int`. An address sanitizer can be helpful when trying to locate a segfault: [gcc - how to use address sanitizer](https://stackoverflow.com/q/47201087/10107454). – paleonix Mar 02 '22 at 17:18
  • Partially solved, thanks to advice from commenters. Using `std::ptrdiff_t` did not help at all. I just changed all the pointers to vectors, and now there are no segmentation faults. But I am not completely satisfied... Thank you @VictorEijkhout – 5Pack Mar 02 '22 at 23:57

1 Answers1

3

I think, it is because, your value (50000*50000 = 2500000000) reached above INT_MAX (2147483647) in c++. As a result, the array access behaviour will be undefined.

So, you should use UINT_MAX or some other types that suits with your usecase.

j23
  • 3,139
  • 1
  • 6
  • 13
  • You should rather use `long int` or `std::int64_t`. `unsigned` will fail for N=100000, while a signed 64 bit integer will work. – paleonix Mar 02 '22 at 15:03
  • 1
    std::ptrdiff_t is the type you are looking for. Signed (not all OpenMP implementations work with unsigned types in their loops), and not unnecessarily large on 32 bit systems. Also long int on Windows is 32 bit so that wouldn't work. – Homer512 Mar 02 '22 at 16:00
  • @paleonix This doesn't fix my segmentation fault... – 5Pack Mar 02 '22 at 16:44