0

I have put together a basic C++ code which reads two matrices from text files into C++ and using the Eigen library solve the generalized eigenvalue problem. This works perfectly and gives me the expected results when using the data type double and MatrixXd.

For a particular instance this code will need to be run at higher precision. From looking at the documentation, Eigen has mpfr support which I have been trying to implement but get the error:

Segmentation fault (core dumped)

I have narrowed down the problem to the code which reads in the matrices from the text files. In the older code which uses the double data type there is no declaration of any mpfr types, and instead of MatrixXmp I use the standard MatrixXd.

This minimal working example code below only concerns the reading in of the file as that is where the error occurs. The matrix file test1.txt just has the simple format (example for a 2 x 2 matrix):

1.368237598319937   8.572948739583564
0.582759275301284   8.457285728753445

Here is the main C++ code

#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
#include <Eigen/Dense>
#include <Eigen/Eigenvalues> 
#include <stdint.h>
#include <stdio.h>
#include <Eigen/MPRealSupport>
using namespace mpfr;
using namespace std;
using namespace Eigen;

#define MAXBUFSIZE  ((int) 1e6)
typedef Matrix<mpreal,Dynamic,Dynamic>  MatrixXmp;
typedef Matrix<mpreal,Dynamic,1>        VectorXmp;

// The following declares a read function to read in a matrix file
MatrixXmp readMatrix(const char *filename)
    {
    int cols = 0, rows = 0;
    mpreal buff[MAXBUFSIZE];

    // Read numbers from file into buffer.
    ifstream infile;
    infile.open(filename);
    while (! infile.eof())
        {
        string line;
        getline(infile, line);

        int temp_cols = 0;
        stringstream stream(line);
        while(! stream.eof())
            stream >> buff[cols*rows+temp_cols++];

        if (temp_cols == 0)
            continue;

        if (cols == 0)
            cols = temp_cols;

        rows++;
        }

    infile.close();

    rows--;

    MatrixXmp result(rows,cols);
    for (int i = 0; i < rows; i++)
        for (int j = 0; j < cols; j++)
            result(i,j) = buff[ cols*i+j ];

    return result;
    };

int main()
{
  // set precision to 256 bits (double has only 53 bits)
  mpreal::set_default_prec(256);

  MatrixXmp A = readMatrix("test1.txt");
}

First I wanted to check that all the linking of the libraries was done correctly so commented out the read line and inserted the example problem from the mpfr Eigen page which compiled and ran without issues. This narrows it down to the read function but I cannot see what the issue is, and it works perfectly when using the double data type. I am sure I am missing something obvious, and any help would be greatly appreciated.

EDIT

Included Stack trace:

*** Segmentation fault
Register dump:

 RAX: 00007fff15cc73e0   RBX: 0000000000000000   RCX: 0000000000000042
 RDX: 0000000000000100   RSI: 0000000000402bff   RDI: 00007fff15cc73e0
 RBP: 00007fff15cc73c0   R8 : 00007fd24417fac0   R9 : 00007fd244174780
 R10: 0000000000000016   R11: 00007fd2445ffae0   R12: 0000000000401650
 R13: 00007fff15cc74f0   R14: 0000000000000000   R15: 0000000000000000
 RSP: 00007fff02b99fa0

 RIP: 0000000000401756   EFLAGS: 00010206

 CS: 0033   FS: 0000   GS: 0000

 Trap: 0000000e   Error: 00000006   OldMask: 00000000   CR2: 02b99fa8

 FPUCW: 0000037f   FPUSW: 00000000   TAG: 00000000
 RIP: 00000000   RDP: 00000000

 ST(0) 0000 0000000000000000   ST(1) 0000 0000000000000000
 ST(2) 0000 0000000000000000   ST(3) 0000 0000000000000000
 ST(4) 0000 0000000000000000   ST(5) 0000 0000000000000000
 ST(6) 0000 0000000000000000   ST(7) 0000 0000000000000000
 mxcsr: 1f80
 XMM0:  00000000000000000000000000000000 XMM1:      00000000000000000000000000000000
 XMM2:  00000000000000000000000000000000 XMM3:  00000000000000000000000000000000
 XMM4:  00000000000000000000000000000000 XMM5:  00000000000000000000000000000000
 XMM6:  00000000000000000000000000000000 XMM7:  00000000000000000000000000000000
 XMM8:  00000000000000000000000000000000 XMM9:  00000000000000000000000000000000
 XMM10: 00000000000000000000000000000000 XMM11: 00000000000000000000000000000000
 XMM12: 00000000000000000000000000000000 XMM13: 00000000000000000000000000000000
 XMM14: 00000000000000000000000000000000 XMM15: 00000000000000000000000000000000

Backtrace:
/home/main.cpp:30(_Z10readMatrixPKc)[0x401756]
/home/main.cpp:101(main)[0x401c22]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7fd243841830]
??:?(_start)[0x401679]

Memory map:

00400000-00404000 r-xp 00000000 08:01 3861463 /home/
00604000-00605000 r--p 00004000 08:01 3861463 /home/
00605000-00606000 rw-p 00005000 08:01 3861463 /home/
01174000-011a6000 rw-p 00000000 00:00 0 [heap]
7fd243298000-7fd2433a0000 r-xp 00000000 08:01 2243272 /lib/x86_64-linux-gnu/libm-2.23.so
7fd2433a0000-7fd24359f000 ---p 00108000 08:01 2243272 /lib/x86_64-linux-gnu/libm-2.23.so
7fd24359f000-7fd2435a0000 r--p 00107000 08:01 2243272 /lib/x86_64-linux-gnu/libm-2.23.so
7fd2435a0000-7fd2435a1000 rw-p 00108000 08:01 2243272 /lib/x86_64-linux-gnu/libm-2.23.so
7fd2435a1000-7fd243620000 r-xp 00000000 08:01 6191906 /usr/lib/x86_64-linux-gnu/libgmp.so.10.3.0
7fd243620000-7fd24381f000 ---p 0007f000 08:01 6191906 /usr/lib/x86_64-linux-gnu/libgmp.so.10.3.0
7fd24381f000-7fd243820000 r--p 0007e000 08:01 6191906 /usr/lib/x86_64-linux-gnu/libgmp.so.10.3.0
7fd243820000-7fd243821000 rw-p 0007f000 08:01 6191906 /usr/lib/x86_64-linux-gnu/libgmp.so.10.3.0
7fd243821000-7fd2439e0000 r-xp 00000000 08:01 2243263 /lib/x86_64-linux-gnu/libc-2.23.so
7fd2439e0000-7fd243be0000 ---p 001bf000 08:01 2243263 /lib/x86_64-linux-gnu/libc-2.23.so
7fd243be0000-7fd243be4000 r--p 001bf000 08:01 2243263 /lib/x86_64-linux-gnu/libc-2.23.so
7fd243be4000-7fd243be6000 rw-p 001c3000 08:01 2243263 /lib/x86_64-linux-gnu/libc-2.23.so
7fd243be6000-7fd243bea000 rw-p 00000000 00:00 0
7fd243bea000-7fd243c00000 r-xp 00000000 08:01 2229287 /lib/x86_64-linux-gnu/libgcc_s.so.1
7fd243c00000-7fd243dff000 ---p 00016000 08:01 2229287 /lib/x86_64-linux-gnu/libgcc_s.so.1
7fd243dff000-7fd243e00000 rw-p 00015000 08:01 2229287 /lib/x86_64-linux-gnu/libgcc_s.so.1
7fd243e00000-7fd243f72000 r-xp 00000000 08:01 6168047 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7fd243f72000-7fd244172000 ---p 00172000 08:01 6168047 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7fd244172000-7fd24417c000 r--p 00172000 08:01 6168047 /usr/lib/x86_64-   linux-gnu/libstdc++.so.6.0.21
7fd24417c000-7fd24417e000 rw-p 0017c000 08:01 6168047 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7fd24417e000-7fd244182000 rw-p 00000000 00:00 0
7fd244182000-7fd2441e5000 r-xp 00000000 08:01 6180286 /usr/lib/x86_64-linux-gnu/libmpfr.so.4.1.4
7fd2441e5000-7fd2443e4000 ---p 00063000 08:01 6180286 /usr/lib/x86_64-linux-gnu/libmpfr.so.4.1.4
7fd2443e4000-7fd2443e6000 r--p 00062000 08:01 6180286 /usr/lib/x86_64-linux-gnu/libmpfr.so.4.1.4
7fd2443e6000-7fd2443e7000 rw-p 00064000 08:01 6180286 /usr/lib/x86_64-linux-gnu/libmpfr.so.4.1.4
7fd2443e7000-7fd2443eb000 r-xp 00000000 08:01 2243269 /lib/x86_64-linux-gnu/libSegFault.so
7fd2443eb000-7fd2445ea000 ---p 00004000 08:01 2243269 /lib/x86_64-linux-gnu/libSegFault.so
7fd2445ea000-7fd2445eb000 r--p 00003000 08:01 2243269 /lib/x86_64-linux-gnu/libSegFault.so
7fd2445eb000-7fd2445ec000 rw-p 00004000 08:01 2243269 /lib/x86_64-linux-gnu/libSegFault.so
7fd2445ec000-7fd244612000 r-xp 00000000 08:01 2230157 /lib/x86_64-linux-gnu/ld-2.23.so
7fd2447d0000-7fd2447d6000 rw-p 00000000 00:00 0
7fd24480f000-7fd244811000 rw-p 00000000 00:00 0
7fd244811000-7fd244812000 r--p 00025000 08:01 2230157 /lib/x86_64-linux-gnu/ld-2.23.so
7fd244812000-7fd244813000 rw-p 00026000 08:01 2230157 /lib/x86_64-linux-gnu/ld-2.23.so
7fd244813000-7fd244814000 rw-p 00000000 00:00 0
7fff15ca8000-7fff15cc9000 rw-p 00000000 00:00 0 [stack]
7fff15de8000-7fff15dea000 r--p 00000000 00:00 0 [vvar]
7fff15dea000-7fff15dec000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
Yeti
  • 401
  • 3
  • 13
  • 2
    `mpreal buff[MAXBUFSIZE]` as a local variable might exceed the stack limit; just for diagnostics, try to make this variable "global", i.e. define it at file level right after the `#define MAXBUFSIZE`... Let us know if it works then or not. – Stephan Lechner Jul 13 '17 at 15:49
  • Given the error is a segfault could you post the stack trace? – IlBeldus Jul 13 '17 at 15:53
  • `while (! infile.eof())` -- You should [read this](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong) – PaulMcKenzie Jul 13 '17 at 16:33
  • @IlBeldus I have added the stack trace to the post. – Yeti Jul 13 '17 at 16:42
  • @PaulMcKenzie Thank you for the link. I have learnt something new :) – Yeti Jul 13 '17 at 16:43
  • @Yeti could you tell us which are lines 30 and 101 of main.cpp? looks like the problem is there – IlBeldus Jul 13 '17 at 16:45
  • @IlBeldus Line 30 is where the function readMatrix is defined and line 101 is where it is called in int main. – Yeti Jul 13 '17 at 16:47
  • @StephanLechner I tried what you suggested and unfortunately the same error occurs. – Yeti Jul 13 '17 at 17:32

1 Answers1

1

You're probably allocating too much stack space, as @StephanLechner said. Namely 32 MB, since MAXBUFSIZE is 1000000 and you made each entry take up at least 32 bytes with mpreal::set_default_prec. That's a lot more than my default 8 MB limit on Mac OS 10.12.5.

I ran your original code and got a seg fault. I changed your code to allocate heap space for buff, and it ran fine: instead of

mpreal buff[MAXBUFSIZE];

write

mpreal *buff = new mpreal[MAXBUFSIZE];

You ought to delete it later of course.

Alex
  • 760
  • 4
  • 12
  • Of course, I should have noticed that. Thank you to you and also to @StephanLechner. – Yeti Jul 13 '17 at 21:03