Cannot use simplest ifstream with LAPACK

  • Thread starter Angelos K
  • Start date
  • Tags
    c++ lapack
In summary, the conversation discusses compiling and running two different programs without any errors or warnings. One program uses LAPACK and the other uses ifstream to read from a file into a vector. The conversation then mentions modifying the LAPACK program to include the function from the ifstream program, which results in a ton of errors. The expert suggests using g++ instead of gcc and mentions that some warnings will still remain.
  • #1
Angelos K
48
0
I have an official LAPACK example from here:

https://software.intel.com/sites/pr.../mkl_sa/11/mkl_lapack_examples/dsyev_ex.c.htm

It compiles and runs without errors or warnings after using

ludi@ludi-M17xR4:~/Desktop/tests$ gcc -Ddsyev=dsyev_ -o sylapack sylapack.c -L/usr/local/lib -llapack -lblas && ./sylapack​

Then, I have a very simple programme using ifstream for reading from a file into a vector. It, too, compiles flawlessly using

ludi@ludi-M17xR4:~/Desktop/tests$ g++ -Wall -pedantic -o justread.x justread.cc && ./justread.x

Here is the latter programme:
#include <fstream>
#include <vector>int read_covariance ()
{
std::vector<double> data;
double tmp;

std::ifstream fin("peano_covariance.data");

while(fin >> tmp)
{
data.push_back(tmp);
}

return 0;
}

int main()
{
read_covariance();
return 0;
}​

I just want to use read_covariance() from the small programme within the first programme. To that end I just modify the start of the LAPACK example, adding the function I want to use. Explicitly, I moddify just the start of the example to

#include <stdlib.h>
#include <stdio.h>
#include <fstream>
#include <vector>

int read_covariance ()
{
std::vector<double> data;
double tmp;

std::ifstream fin("peano_covariance.data");

while(fin >> tmp)
{
data.push_back(tmp);
}

return 0;
}/* DSYEV prototype */
extern void dsyev( char* jobz, char* uplo, int* n, double* a, int* lda,
double* w, double* work, int* lwork, int* info );
/* Auxiliary routines prototypes */
extern void print_matrix( char* desc, int m, int n, double* a, int lda );

/* Parameters */​

Leaving it otherwise unmodified. I added some unmodified lines to make clear where I am. I immediately get a ton of errors:

ludi@ludi-M17xR4:~/Desktop/tests$ gcc -Ddgeev=dgeev_ -o combo combo.cc -L/usr/local/lib -llapack -lblas && ./combo
combo.cc: In function ‘int main()’:
combo.cc:107:74: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
dsyev( "Vectors", "Upper", &n, a, &lda, w, &wkopt, &lwork, &info );
^
combo.cc:107:74: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
combo.cc:111:72: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
dsyev( "Vectors", "Upper", &n, a, &lda, w, work, &lwork, &info );
^
combo.cc:111:72: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
combo.cc:118:49: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
print_matrix( "Eigenvalues", 1, n, w, 1 );
^
combo.cc:120:72: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
print_matrix( "Eigenvectors (stored columnwise)", n, n, a, lda );
^
/tmp/ccZrNqc0.o: In function `read_covariance()':
combo.cc:(.text+0x3f): undefined reference to `std::basic_ifstream<char, std::char_traits<char> >::basic_ifstream(char const*, std::_Ios_Openmode)'
combo.cc:(.text+0x73): undefined reference to `std::istream::eek:perator>>(double&)'
combo.cc:(.text+0x88): undefined reference to `std::basic_ios<char, std::char_traits<char> >::eek:perator void*() const'
combo.cc:(.text+0xa6): undefined reference to `std::basic_ifstream<char, std::char_traits<char> >::~basic_ifstream()'
combo.cc:(.text+0xda): undefined reference to `std::basic_ifstream<char, std::char_traits<char> >::~basic_ifstream()'
/tmp/ccZrNqc0.o: In function `main':
combo.cc:(.text+0x1af): undefined reference to `dsyev(char*, char*, int*, double*, int*, double*, double*, int*, int*)'
combo.cc:(.text+0x236): undefined reference to `dsyev(char*, char*, int*, double*, int*, double*, double*, int*, int*)'
/tmp/ccZrNqc0.o: In function `std::vector<double, std::allocator<double> >::_M_insert_aux(__gnu_cxx::__normal_iterator<double*, std::vector<double, std::allocator<double> > >, double const&)':
combo.cc:(.text._ZNSt6vectorIdSaIdEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPdS1_EERKd[_ZNSt6vectorIdSaIdEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPdS1_EERKd]+0x263): undefined reference to `__cxa_end_catch'
combo.cc:(.text._ZNSt6vectorIdSaIdEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPdS1_EERKd[_ZNSt6vectorIdSaIdEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPdS1_EERKd]+0x276): undefined reference to `__cxa_begin_catch'
combo.cc:(.text._ZNSt6vectorIdSaIdEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPdS1_EERKd[_ZNSt6vectorIdSaIdEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPdS1_EERKd]+0x2df): undefined reference to `__cxa_rethrow'
/tmp/ccZrNqc0.o: In function `std::vector<double, std::allocator<double> >::_M_check_len(unsigned long, char const*) const':
combo.cc:(.text._ZNKSt6vectorIdSaIdEE12_M_check_lenEmPKc[_ZNKSt6vectorIdSaIdEE12_M_check_lenEmPKc]+0x4c): undefined reference to `std::__throw_length_error(char const*)'
/tmp/ccZrNqc0.o: In function `__gnu_cxx::new_allocator<double>::deallocate(double*, unsigned long)':
combo.cc:(.text._ZN9__gnu_cxx13new_allocatorIdE10deallocateEPdm[_ZN9__gnu_cxx13new_allocatorIdE10deallocateEPdm]+0x1c): undefined reference to `operator delete(void*)'
/tmp/ccZrNqc0.o: In function `__gnu_cxx::new_allocator<double>::allocate(unsigned long, void const*)':
combo.cc:(.text._ZN9__gnu_cxx13new_allocatorIdE8allocateEmPKv[_ZN9__gnu_cxx13new_allocatorIdE8allocateEmPKv]+0x2c): undefined reference to `std::__throw_bad_alloc()'
combo.cc:(.text._ZN9__gnu_cxx13new_allocatorIdE8allocateEmPKv[_ZN9__gnu_cxx13new_allocatorIdE8allocateEmPKv]+0x3c): undefined reference to `operator new(unsigned long)'
/tmp/ccZrNqc0.o:(.eh_frame+0x4b): undefined reference to `__gxx_personality_v0'
collect2: error: ld returned 1 exit status
ludi@ludi-M17xR4:~/Desktop/tests$

Can anyone offer guidance??
 
Last edited:
Technology news on Phys.org
  • #2
Emphasis mine:
Angelos K said:
gcc -Ddgeev=dgeev_ -o combo combo.cc -L/usr/local/lib -llapack -lblas && ./combo
That you are compiling and linking with gcc (rather than g++) explains a large number of your errors. The problem is that gcc doesn't know to use the standard library. g++ does. So use g++. After all, you are writing c++, not c.

The remaining warnings will be just that, warnings. The C wrapper to the fortran function dsyev is ancient. Strictly speaking, it's illegal to pass something like "Vector" as a char*. The compiler is warning you about that.
 
  • #3
Thank you so much! What you say is so logical and resolves many errors. But there are still some errors left:

ludi@ludi-M17xR4:~/Desktop/tests$ g++ -Ddsyev=dsyev_ -o combo.x combo.cc -L/usr/local/lib -llapack -lblas && ./combo.x
combo.cc: In function ‘int main()’:
combo.cc:107:74: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
dsyev( "Vectors", "Upper", &n, a, &lda, w, &wkopt, &lwork, &info );
^
combo.cc:107:74: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
combo.cc:111:72: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
dsyev( "Vectors", "Upper", &n, a, &lda, w, work, &lwork, &info );
^
combo.cc:111:72: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
combo.cc:118:49: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
print_matrix( "Eigenvalues", 1, n, w, 1 );
^
combo.cc:120:72: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
print_matrix( "Eigenvectors (stored columnwise)", n, n, a, lda );
^
/tmp/cciDZkcq.o: In function `main':
combo.cc:(.text+0x1af): undefined reference to `dsyev_(char*, char*, int*, double*, int*, double*, double*, int*, int*)'
combo.cc:(.text+0x236): undefined reference to `dsyev_(char*, char*, int*, double*, int*, double*, double*, int*, int*)'
collect2: error: ld returned 1 exit status
ludi@ludi-M17xR4:~/Desktop/tests$​
 
  • #4
All errors disappeared by using C linkage. Every occurrence of

extern void function
{...}

was replaced by

extern "C"
{
void function
{...}
}

Specifically, I now use:
/* DSYEV prototype */
extern "C"{
void dsyev( char* jobz, char* uplo, int* n, double* a, int* lda,
double* w, double* work, int* lwork, int* info );
}
/* Auxiliary routines prototypes */
extern "C"{
void print_matrix( char* desc, int m, int n, double* a, int lda );
}
I kind of understand what extern "C" does. Could someone explain what extern did? Was it spurious?

The warnings I still get are all of the type.

combo.cc:110:74: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
dsyev( "Vectors", "Upper", &n, a, &lda, w, &wkopt, &lwork, &info );
^
combo.cc:110:74: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
I think they are no big deal, but if someone knows how to remedy them...
 
Last edited:
  • #5
Angelos K said:
All errors disappeared by using C linkage. Every occurrence of

extern void function
{...}

was replaced by

extern "C"
{
void function
{...}
}

Specifically, I now use:
/* DSYEV prototype */
extern "C"{
void dsyev( char* jobz, char* uplo, int* n, double* a, int* lda,
double* w, double* work, int* lwork, int* info );
}
/* Auxiliary routines prototypes */
extern "C"{
void print_matrix( char* desc, int m, int n, double* a, int lda );
}
I kind of understand what extern "C" does. Could someone explain what extern did? Was it spurious?

The warnings I still get are all of the type.

combo.cc:110:74: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
dsyev( "Vectors", "Upper", &n, a, &lda, w, &wkopt, &lwork, &info );
^
combo.cc:110:74: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
I think they are no big deal, but if someone knows how to remedy them...

According to some documentation I found for dsyev (http://www.math.utah.edu/software/lapack/lapack-d/dsyev.html), there is a mismatch between your actual arguments (in the call to dsyev()) and the parameters that are described in the documentation.

Here's a comparison between the input formal parameters you show in the dsyev prototype above, and those described in the documentation:
Code:
Parameter Your prototype....Docs I found
jobz (in)       char *            CHARACTER* 1 <--- This is a single character, not a pointer
uplo (in)       char *            CHARACTER*1 <---- Ditto
n (in)          int *             INTEGER  <--- In your prototype, n is a pointer; in the docs it's an integer, which is not the same.
LDA (in)        int *             INTEGER  <--- Ditto
LWORK (in)      int *             INTEGER <--- Ditto
I didn't list the in/out or out parameters, which do need to be pointers when you're calling this routine from C or C++. The in parameters shouldn't be pointers (addresses) as you have them. Since the parameters you show in your prototype agree with the types you show in the call to dsyev, I don't believe that the compiler will issue a warning, but it seems likely to me that you'll get very inaccurate results. This business of the parameters is the same thing I said in the other thread you posted, so it doesn't seem to have stuck with you.

The two warnings you show come from using string constants in your calls to dsyev (e.g., "Vectors" and "Upper") instead of character arrays. In other words, for these first two parameters, the prototype you show expects them to have been declared as char jobz[] = "Vectors" and char uplo[] = "Upper". What seems more problematic to me is that the LAPACK dsyev function (according to the docs in the link I show, and elsewhere) is expecting a single constant for jobz and uplo, 'V' and 'U', respectively.[/code]
 
  • #6
I don't know for your problem but please, test fin.isopen() before reading it.
If the file doesn't exist you will have a hard to find segmentation fault.
 
  • #7
Angelos K said:
All errors disappeared by using C linkage. Every occurrence of

extern void function
{...}

was replaced by

extern "C"
{
void function
{...}
}
You shouldn't be declaring the functions in the lapack library. You should instead be using a header file that comes with the library. If that header file was written for use in C but not C++ (i.e., it doesn't wrap function declarations within an extern "C" block, you can use
Code:
extern "C" {
#include "goofy_c_only_header.h"
}
I kind of understand what extern "C" does. Could someone explain what extern did? Was it spurious?
It was not spurious.

Consider the following:
Code:
int foo () { return 42; }
int foo (int num) { return num + 42; }
double foo (double num1, int num2=42) { return num1 + num2; }
The above code is perfectly legal C++ code. C++ has overloading. C doesn't; the above is illegal in C. Actually, it's worse than illegal in C; it falls in that terrible category of "illegal" called "undefined behavior". The compiler/linker is nice if it does detect that their are multiple definitions of foo. It doesn't have to.

This possibility of overloading in C++ (but not in C) is the reason you absolutely need to use extern "C" to call a C function from C++ code. C++ compilers mangle function names so as to distinguish foo() from foo(int) and foo(double). For example, the C++ function double foo(double num1, int num2) becomes __Z3foodi on my computer with my compiler. When compiled as a C function, the same function becomes _foo with my compiler. These different linkage rules for C versus C++ means you need to tell the compiler that the C functions you are calling are indeed C functions, not C++ functions.

The warnings I still get are all of the type.

combo.cc:110:74: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
dsyev( "Vectors", "Upper", &n, a, &lda, w, &wkopt, &lwork, &info );
I think they are no big deal, but if someone knows how to remedy them...
In this case, those warnings are benign. Those warnings do however need to be there. You are (potentially) invoking undefined behavior. What if dysev changes the contents of that string? That's undefined behavior. The function dysev doesn't do that, but the prototype says that it might well do exactly that. A good compiler will warn you when you supply a const array to a function that takes a non-const array as an argument.
 

1. What is LAPACK and how does it relate to ifstream?

LAPACK (Linear Algebra Package) is a software library used for numerical linear algebra operations. It provides routines for solving systems of linear equations, linear least squares problems, eigenvalue problems, and singular value decomposition. LAPACK can be used with ifstream to read in data from a file and perform linear algebra operations on the data.

2. Why can't I use the simplest ifstream with LAPACK?

The simplest ifstream, which is the basic input stream class for reading data from a file, does not have the necessary functions and capabilities to work with LAPACK. LAPACK requires a more advanced ifstream implementation, such as the fstream class, which provides additional functions and methods for manipulating data and performing linear algebra operations.

3. How can I use ifstream with LAPACK?

In order to use ifstream with LAPACK, you will need to use a more advanced ifstream implementation, such as the fstream class. This class provides functions and methods for manipulating data and performing linear algebra operations, making it compatible with LAPACK. You will also need to ensure that your data is formatted correctly for use with LAPACK.

4. Are there any alternatives to using ifstream with LAPACK?

Yes, there are alternatives to using ifstream with LAPACK. You can use other input methods, such as user input or data generated within the program, to supply data for LAPACK calculations. Additionally, there are other libraries that provide similar linear algebra functionality to LAPACK, such as BLAS (Basic Linear Algebra Subprograms) and ATLAS (Automatically Tuned Linear Algebra Software).

5. Can I use ifstream with LAPACK in any programming language?

No, you cannot use ifstream with LAPACK in any programming language. LAPACK is primarily written in Fortran and is commonly used with programming languages that support Fortran, such as C and C++. However, there are also versions of LAPACK that have been implemented in other programming languages, such as Python and Java, which may have different requirements for using ifstream with LAPACK.

Similar threads

  • Programming and Computer Science
Replies
5
Views
1K
  • Programming and Computer Science
Replies
4
Views
1K
  • Programming and Computer Science
Replies
4
Views
6K
  • Programming and Computer Science
Replies
1
Views
1K
  • Programming and Computer Science
Replies
4
Views
4K
  • Programming and Computer Science
Replies
13
Views
1K
  • Programming and Computer Science
Replies
4
Views
3K
  • Programming and Computer Science
Replies
11
Views
4K
  • Programming and Computer Science
Replies
6
Views
3K
  • Programming and Computer Science
Replies
9
Views
4K
Back
Top