MIPP icon indicating copy to clipboard operation
MIPP copied to clipboard

Segmentation fault when calling mipp::load<float>()

Open psycha0s opened this issue 4 years ago • 4 comments

I get a segmentation fault when I call mipp::load<float>(ptr) when optimizations are turned off (my GCC flags -O0 -march=skylake). As far as I can tell, it happens because the body of the function is not inlined. It can be fixed by adding an attribute to all such functions (__attribute__((always_inline)) for GCC and Clang). I'm not sure about MSVS, though. Is it a known issue or maybe I just don't know/understand something? I wouldn't like to completely disable intrinsics for my debug builds. Is there a chance you will add this attribute?

psycha0s avatar Sep 13 '20 14:09 psycha0s

Hi @psycha0s,

I think it is not normal to have a segfault when calling a mipp::load. The only reason why you should have a segfault is because you are loading data outside the allocated memory. Are you confident with your code? Could you share a short code example that produces the segfault?

kouchy avatar Sep 14 '20 07:09 kouchy

I tried both, aligned and unaligned loads. Also, I tried to use mipp::malloc() and to allocate+align the pointer manually. I get crash each time I call any function with a simd intrinsic if it's not inlined. I'm using GCC 10.1.0 from the MSYS2 project on Windows 10 with the following arguments: -g3 -Wall -Wextra -march=sandybridge -std=gnu++2a -DMIPP_ALIGNED_LOADS And here is a simple example to reproduce the issue on my system:

#include "mipp.h"

int main()
{
	auto ptr = mipp::malloc<double>(100);
	mipp::load<double>(ptr); // SEGFAULT
	return 0;
}

I narrowed it down to this:

#include "mipp.h"

__m256d load(const double* ptr)
{
	return _mm256_load_pd(ptr);
}

int main()
{
	auto ptr = mipp::malloc<double>(100);
	auto reg = _mm256_load_pd(ptr); // success
	reg = load(ptr);                // SEGFAULT
	return 0;
}

As soon as I change my compiler optimisation level to -O3 or just force the load() function to be inlined, everything works well:

#include "mipp.h"

inline __m256d __attribute__((always_inline)) load(const double* ptr)
{
	return _mm256_load_pd(ptr);
}

int main()
{
	auto ptr = mipp::malloc<double>(100);
	auto reg = _mm256_load_pd(ptr); // success
	reg = load(ptr);                // success
	return 0;
}

psycha0s avatar Sep 14 '20 08:09 psycha0s

I'm facing a similar problem as well.

Here's my simple function:

void AddMIPPLLR(std::vector<mippf>& L_d, const std::vector<mippf>& L_s,
                const int GFq) {
    assert(L_d.size() == GFq / mippN && L_d.size() == GFq / mippN);
    for (int i = 0; i < GFq / mippN; i++) {
        L_d[i] = mipp::add(L_d[i], L_s[i]);
    }
}

These lines run well, but as long as I set gcc optimization, the mipp::add will raise a segment fault.

What's more, if I change the line L_d[i] = mipp::add(L_d[i], L_s[i]); into L_d[i] += L_s[i], it will raise segment fault no matter whether gcc optimization is set.

It's interesting that segment fault would only be raised after a few iterators.

add_definitions("-DMIPP_ALIGNED_LOADS") is set in CMakeLists.txt.

Sciroccogti avatar May 02 '21 10:05 Sciroccogti

Hi @Sciroccogti,

I think that you can't have a std::vector of mipp::Reg or if you do that you need to load your register before calling mipp::add.

I hope it helps.

kouchy avatar Oct 18 '21 15:10 kouchy