Using OpenBLAS LAPACKE in Visual Studio - c++

i need some linear algebra in my project and want use OpenBLAS for this. I downloaded the precompiled version (64bit version) and unpacked it to my projectfolder. In Visual Studio, i added include-, bin-, and lib-folder to my Project and ran the this example without problems.
Next, i wanted to look at LAPACK, so i added lapacke.h to the includes, which is in the same directory as cblas.h and is included in the official download. But now i get hundreds of errors, for every function, as if a lib file was missing or something. E.g. for this line
85 lapack_complex_float lapack_make_complex_float( float re, float im );
i get
PATH\include\lapacke.h(85): error C2146: syntax error: missing ';' before identifier 'lapack_make_complex_float'
I can't find any further information on how to set up OpenBLAS/LAPACK, they usually just say 'include the files', which i have. Otherwise the cblas example wouldn't run either. And the (relevant) examples i can find only use cblas.h, not lapacke.h
Can some tell me what i'm doing wrong?

The problem is that OpenBlas uses C99 _Complex by default. This is not supported by Visual C++. You can solve this by using standard library definitions before including lapacke.h:
#include <complex>
#define lapack_complex_float std::complex<float>
#define lapack_complex_double std::complex<double>
#include <lapacke.h>

Using std::complex is problematic unless OpenBLAS was built with LAPACK_COMPLEX_CPP otherwise the library uses a different complex type internally, usually C99 _Complex.
Modern versions of the Microsoft compiler (e.g. the one in VSTUDIO 2022) support a similar "_Complex" mechanism. Therefore I include the following header file prior to "lapacke.h"
#ifdef _MSC_VER
#include <complex.h>
#define LAPACK_COMPLEX_CUSTOM
typedef _Dcomplex lapack_complex_float;
typedef _Fcomplex lapack_complex_double;
#define lapack_complex_float_real(z) (real(z))
#define lapack_complex_float_imag(z) (imag(z))
#endif // _MSC_VER
See the lapack.h header file that ships with OpenBLAS how #define LAPACK_COMPLEX_CUSTOM overrides complex variable type definitions

Related

OpenCL 2.x(C++ bindings): undefined identifier

Edit: adding OpenCL.lib in library files section of visual studio solved the problem.
With cl2.hpp from this github repository pointed by khronos site, I get 60-70 similar errors when I try to compile a C++ dll project with OpenCL-C++-implementation functions to export.
'CL_DEVICE_QUEUE_ON_HOST_PROPERTIES': undeclared identifier
// I'm not using this, I'm newly converting a v1.2 C++ binding-based
// project to a v2.0 one
starting of the file is:
using namespace std;
#define __CL_ENABLE_EXCEPTIONS
#include <CL\cl2.hpp>
and the remaining lines are not underlined with red(visual studio). There are some compile time constants I need to add maybe, but I don't know which constants.
What is missing?
this code(there isn't any other code in project) also gives same error:
#include <CL\cl2.hpp>
I had the same errors and something that worked for me was to add the following prior to #include <cl2.hpp>
#define CL_HPP_TARGET_OPENCL_VERSION 120
#define CL_HPP_MINIMUM_OPENCL_VERSION 120
#include <cl2.hpp>

HYPRE blas build error with VS 2015

I installed VS 2015 Professional. I installed the latest HYPRE, from the Lawrence Livermore website. I then configured it using CMake and proceeded to build, and I started getting BLAS (dnrm2.c) build errors:
2> dnrm2.c
2> 1>
C:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\ucrt\math.h(454): error C2059: syntax error: '('
The line of code triggering the error in dnrm2.c is:
#include "math.h"
which points to the file:
c:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\ucrt\math.h
I looked up this error and found some suggestions such as this to change the include to:
#include <cmath>
and to edit the HYPRE project settings in: Configuration > C/C++ > Advanced > Compile As to Compile As C++ (/TP)
which I did, but I still see same error, since apparently the same header path to math.h is included from cmath as well:
#else /* _STD_USING */
#include <math.h>
#endif /* _STD_USING */
I've even tried re-installing VS 2015 without any luck (same errors). Appreciate any ideas on what's going on here, and how to resolve this. I guess I could try a minimalist example in VS 2015 that includes the math.h and report back, if that helps.
EDIT
My minimalist example:
#include "math.h"
int main() {
double d1 = sqrt(4.0);
float d2 = abs(4.0);
return 0;
}
appears to be building OK. I tried to set the project the same way to Compile as C (or C++, didn't matter). This doesn't really help me though.
OK, the problem here is with HYPRE source it looks like. They have this in a file f2c.h included before including the math.h:
//#undef abs
//#define abs(x) ((x) >= 0 ? (x) : -(x))
//#endif
When I commented it out (since this is already defined in the standard), then it gets past that build error. Of course I run into other build errors. I'm trying to tackle those separately.
EDIT: It's not as simple as that because they (HYPRE) actually rely on their own definition of abs. So I had undo the above and change the order of some includes so that the undef actually made sense. Either way, this is a HYPRE source code problem.
If you succeed in compiling the HYPRE on VS2015, Could you send your VS2015 program to me!
My major is Geophysics modeling and inversion.
MY email is schoolhui#hotmail.com
Thank you very much!
I've just commented
_Check_return_ int __cdecl abs(_In_ int _X);
in
c:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\ucrt\math.h
and then HYPRE was successfully compiled!
Then, I've uncommented "abs".

TBB on Windows XP (using in OpenCV) - error entry point InitializeCriticalSectionEx

I tried to compile TBB which I want to use on OpenCV. I am using Windows XP and Visual Studio 2010 C++. When I compiled TBB 4.4 I got the error
"The procedure entry point InitializeCriticalSectionEx could not be located in the dynamic link library KERNEL32.dll."
The error is similar but under little different conditions like here:
http://answers.opencv.org/question/6151/opencv_createsamplesexe-entry-point-problem-with-xp/
In my case I cannot run the program at all. I tried the solution described there, so I renamed InitializeCriticalSectionEx to InitializeCriticalSection and removed parameter 2 and 3.
OpenCV claimes the bug is not on their side. I know OpenCV uses this:
#if (_WIN32_WINNT >= 0x0600)
InitializeCriticalSectionEx(&cs, 1000, 0);
#else
InitializeCriticalSection(&cs);
#endif
I know this should not make any problems but I commented some lines to keep InitializeCriticalSection(&cs); only. I recompiled the OpenCV and still the same error. Finally I have found in TTB:
tbb44_20160627oss\include\tbb\machine\windows_api.h
__TBB_WINBASEAPI BOOL WINAPI TryEnterCriticalSection( LPCRITICAL_SECTION );
__TBB_WINBASEAPI BOOL WINAPI InitializeCriticalSectionAndSpinCount( LPCRITICAL_SECTION, DWORD );
// Overloading WINBASEAPI macro and using local functions missing in Windows XP/2003
#define InitializeCriticalSectionEx inlineInitializeCriticalSectionEx
I also find the word "InitializeCriticalSectionEx" in opencv_core310d.dll and opencv_core310.dll. Does the overload really work and why I got the error? How could I fix it?
Update:
the definition in OpenCV
#ifndef _WIN32_WINNT // This is needed for the declaration of TryEnterCriticalSection in winbase.h with Visual Studio 2005 (and older?)
#define _WIN32_WINNT 0x0400 // http://msdn.microsoft.com/en-us/library/ms686857(VS.85).aspx
#endif
"The procedure entry point InitializeCriticalSectionEx could not be located in the dynamic link library KERNEL32.dll."
This is a standard error that Windows displays when you try to run a program that contains a statically-bound call to a function in a DLL that does not exist.
The InitializeCriticalSectionEx function is not available on Windows XP, but the version of the library that you have contains code that calls this function.
OpenCV claimes the bug is not on their side. I know OpenCV uses this:
#if (_WIN32_WINNT >= 0x0600)
InitializeCriticalSectionEx(&cs, 1000, 0);
#else
InitializeCriticalSection(&cs);
#endif
OpenCV's workaround is a compile-time solution. It determines at the point when the library is compiled which version of Windows is being targeted, and uses that information to generate a call to the appropriate version of the function.
There are two possibilities for why this is going wrong in your case:
You are using the OpenCV library in binary form, and the binary that you have was compiled to target Windows Vista and later. You can solve this by obtaining the source code for OpenCV and compiling it yourself, either as a DLL or a static library.
You are compiling with _WIN32_WINNT set to 0x0600 or later. By default, the Windows headers define this symbol to the latest available version. You have to explicitly define an earlier target version if you want it. To arrange for targeting Windows XP, add the following code at the top of your code file (probably in your precompiled header):
#include <WinSDKVer.h>
#define _WIN32_WINNT _WIN32_WINNT_WINXP
#include <SDKDDKVer.h>

Does Visual Studio provide the C library’s isnormal()?

I’m building a C++ library with Visual Studio Express 2013. I’d like to call the isnormal function from cmath, but the VS library only seems to have _isnan and _finite (and they’re in cfloat, not cmath).
It also provides _fpclass, which I assume corresponds to fpclassify. Is the following macro a suitable replacement for isnormal?
#ifdef _WIN32
#define isnormal(x) (_fpclass(x) == _FPCLASS_NN || _fpclass(x) == _FPCLASS_PN)
#endif
According to this blog post isnormal is at least present in MSVC2013's <math.h>. Therefore, in <cmath> you should find the corresponding std::isnormal (You remembered to use namespace std, right?). If not, you'll have to fall back to the C header.
(Or maybe fix/update your MSVC installation - MGetz' comment shows that his VS2013 Express installation has std::isnormal)

Automatically Including OpenCV Libraries of Different Versions

I've been automatically including the opencv library files for my c++ code on Visual Studio 2008 on Windows 7 with the following code:
#ifndef NDEBUG
#pragma comment(lib, "opencv_core231d.lib")
#pragma comment(lib, "opencv_highgui231d.lib")
#pragma comment(lib, "opencv_imgproc231d.lib")
#else
#pragma comment(lib, "opencv_core231.lib")
#pragma comment(lib, "opencv_highgui231.lib")
#pragma comment(lib, "opencv_imgproc231.lib")
#endif
but I run into trouble when the system has a different version of the opencv library installed because the .lib files have the version (in this case, 2.31) in the filename. Is there a good way to automatically or near-automatically detect what version of the opencv library is available then slide in the appropriate version string into the pragma?
There are small changes between different OpenCV versions - not much, but enough to crash your app when you change from 2.0 to 2.2 or from 2.2 to 2.3.1. Also, the beta 2.4 release has enough changes from previous ones.
So best is to test your app with an OpenCV version, and deliver it with those dlls only.
A small example:
Mat a(3,3,CV_8UC3);
a.setTo( Scalar(10) ); // in 2.3.1 will set all channels to 10,
// in 2.2 will only set first channel.
The corresponding 2.2 call would be
a.setTo(Scalar::all(10));
Or
a = 0; // runs fine on 2.3.1. Equivalent to setTo().
// Does not compile on earlier versions
Another example is cv::drawPoly(), which has a different signature on 2.2 and 2.3.1.
Given the fact that those changes are not well documented, the chance to miss one of them by mistake is really high.
I have worked out a solution to having code run on various versions of OPENCV by merging the following articles:
How to make a string out of macros
Concatenating strings in macros
Pragma statements in #defines with support for VS2008 here on MSDN
Bonus: How to have global settings defined in a solution
As noted, this can cause some serious grief if you pop between incompatible versions but for those versions and features supported this may be useful to some. Use this technique to set the opencv version once and have your code automatically link to the desired version by either
define the OPENCV_VERSIONin one place in your source code
Define it in a Property Sheet
Define it in a system environment variable.
My code ended up like so:
#include <iostream>
// #define OPENCV_VERSION $(OPENCV_VERSION)
// #define OPENCV_VERSION 220
#define QUOTE(name) #name
#define STR(macro) QUOTE(macro)
#define LINK_TO_OPENCV(libname) __pragma(comment(lib, "opencv_" #libname STR(OPENCV_VERSION)))
#define LINK_TO_OPENCV_DEBUG(libname) __pragma(comment(lib, "opencv_" #libname STR(OPENCV_VERSION) "d"))
#ifndef NDEBUG
LINK_TO_OPENCV_DEBUG("core")
LINK_TO_OPENCV_DEBUG("highgui")
LINK_TO_OPENCV_DEBUG("imgproc")
#else
LINK_TO_OPENCV("core")
LINK_TO_OPENCV("highgui")
LINK_TO_OPENCV("imgproc")
#endif
int main()
{
std::cout << STR(LINK_TO_OPENCV("core")) << "\n";
return 0;
}
And now to set the OPENCV_VERSION anywhere you like. For example, you can have a single header file included by everyone that has the line:
#define OPENCV_VERSION 220
Or you can goto Project->Properties->C/C++->Preprocessor and set Preprocessor Definitions to OPENCV_VERSION=220. Or you can do the same thing in a shared property sheet for the entire solution.
Or, and this is important, you can use this technique to define a global environment variable in windows itself called OPENCV_VERSION_ENV and set its value to the version code (say, 220). Then you can put set the preprocessor definition to OPENCV_VERSION=$(OPENCV_VERSION_ENV) and you will bring in the environment variable into the link command. You CANNOT do a #define OPEN_VERSION $(OPENCV_VERSION_ENV) but since the property pages will automatically translate $(macros) we can get environment variables there.