help-octave
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Octave 3.6.4 VS2010 and the C++ API


From: Mike Puglia
Subject: Re: Octave 3.6.4 VS2010 and the C++ API
Date: Wed, 25 Sep 2013 04:55:27 -0700 (PDT)

Hi Michael,

I think I've found the source of the complex matrix multiplication problem I'm having.  The xgemm function in CMatrix.h tests a couple cases before executing a LAPACK function to do the multiplication.  For most cases, ZGEMM is called and this works correctly in all builds.  However, if a 1xn matrix A is multiplied by a nx1 matrix B, as in c = A*B, XZDOTU is called instead and in the VS2010 build the result is not always (ever?) correct.  The octfile below should reproduce the problem.

It seems that this is a problem with the BLAS/LAPACK/ATLAS package being used in the VS2010 build.  Does this sound correct?  (I've never understood the difference between these three things, so maybe now is a good time to learn.)  There are some posts from 2007/08 that touch on this issue with XZDOTU.  Any information you might have about the packages used in the build (or how to find that information) would be greatly appreciated.

https://mailman.cae.wisc.edu/pipermail/bug-octave/2008-March/012009.html

https://mailman.cae.wisc.edu/pipermail/bug-octave/2007-October/010101.html

MTP

#include <octave/oct.h>

DEFUN_DLD (complex_mult_test_oct, args, nargout,
"-*- texinfo -*-\n\
@deftypefn  {Function File} address@hidden, @var{b}, @var{c}, @var{d}] =} complex_mult_test_oct ()\n\
Test complex matrix multiplication.\n\
@end deftypefn")
{  
int nargin = args.length ();
octave_value_list retval;
      
if (nargin != 0)
{
print_usage();
}
else
{
ComplexMatrix a(2,2);
a(0,0) = Complex(0.0,0.0);
a(0,1) = Complex(1.0,0.0);
a(1,0) = Complex(0.0,0.0);
a(1,1) = Complex(1.0,0.0);
ComplexMatrix b(2,2);
b(0,0) = Complex(0.0,0.0);
b(0,1) = Complex(0.0,0.0);
b(1,0) = Complex(1.0,0.0);
b(1,1) = Complex(1.0,0.0);
/******** Test 1 *********/
//The following compiles and executes correctly on both the MINGW and VS2010 builds.
//The multiplication operator in this case calls xgemm->ZGEMM.
ComplexMatrix c = a*b;
/******** Test 2 *********/
//The following compiles on VS2010 build, but does not execute correctly.
//The multiplication operator in this case calls xgemm->XZDOTU, and XZDOTU seems to have a problem in the VS2010 build.
ComplexMatrix d = a.extract(0,0,0,1)*b.extract(0,0,1,0);

retval.append(a);
retval.append(b);
retval.append(c);
retval.append(d);
}
    return retval;
}


From: Mike Puglia <address@hidden>
To: Michael Goffioul <address@hidden>
Cc: "address@hidden" <address@hidden>
Sent: Saturday, September 21, 2013 11:00 AM
Subject: Re: Octave 3.6.4 VS2010 and the C++ API

Hi,

I have found another seemingly major difference between between the VS2010 and MINGW builds, and this would seem to be a bug, rather than a difference in the API definition.  I just wanted to confirm before looking further into this.

The oct file below is a simple demonstration of a complex matrix multiplication.  In the MINGW build, it correctly results in c = 1;  In the VS2010 build it incorrectly results in c =  5.2998e-315 + 2.3146e-245i.  I can compile and link in both platforms with no errors or warnings coming from mkoctfile.

Looking at the header definition of the complex matrix multiplication, it would seem that it is exposed to the DLL, since it is decorated with extern OCTAVE_API.  Also, other members of the ComplexMatrix class (like transpose() and conj()) are exposed and do work correctly in the VS2010 build.

Before I look into this further, do you have any thoughts on what might be happening with the complex matrix multiplication?

And following up on the original issue, the work-around for the xleftdiv() issue below does exist.  The solve() method is exposed to the API through the Matrix classes and can be used to write an xleftdiv() function locally with out too much effort (though it is of course messier than having it in the API).

Thanks is advance for your help.

MTP



#include <octave/oct.h>

DEFUN_DLD (complex_mult_test_oct, args, nargout,
"-*- texinfo -*-\n\
@deftypefn  {Function File} address@hidden, @var{b}, @var{c}, @var{d}] =} complex_mult_test_oct ()\n\
Test complex matrix multiplication.  c = a*b.\n\
@end deftypefn")
{  
int nargin = args.length ();
octave_value_list retval;
     
if (nargin != 0)
{
print_usage();
}
else
{
ComplexMatrix a(1,2);
a(0,0) = Complex(0.0);
a(0,1) = Complex(1.0);
ComplexMatrix b(2,1);
b(0,0) = Complex(0.0);
b(1,0) = Complex(1.0);
ComplexMatrix c = a*b;
Complex d = Complex(0.0)*Complex(0.0) + Complex(1.0)*Complex(1.0);

retval.append(a);
retval.append(b);
retval.append(c);
retval.append(d);
}
    return retval;
}




From: Mike Puglia <address@hidden>
To: Michael Goffioul <address@hidden>
Cc: "address@hidden" <address@hidden>
Sent: Thursday, September 19, 2013 11:01 PM
Subject: Re: Octave 3.6.4 VS2010 and the C++ API

Thank you for the help.  You have saved me a great deal.

Off-hand, can you think of anything in the API that is exposed and can achieve the same functionality?  Specifically I'll need to somehow replicate:

extern ComplexMatrix xleftdiv (const ComplexMatrix& a, const ComplexMatrix& b, MatrixType &typ, blas_trans_type transt = blas_no_trans);

I'm guessing a complete recompile is going to be a bit beyond my abilities/resources at the moment.  I saw the scripts and pre-compiled VS2010 packages you've posted at Octave for Windows though.  Will those work for v3.6.4?  Generally, how would I proceed with a compilation?  I assume I'll need Cygwin to run the sh scripts?  Do the scripts work in conjunction with the pre-compiled libraries, so that a complete recompile would not be necessary if only the functions in xdiv.h are decorated/exposed?

Thanks again for the help.


From: Michael Goffioul <address@hidden>
To: Mike Puglia <address@hidden>
Cc: "address@hidden" <address@hidden>
Sent: Thursday, September 19, 2013 10:01 PM
Subject: Re: Octave 3.6.4 VS2010 and the C++ API

On Thu, Sep 19, 2013 at 7:47 AM, Mike Puglia <address@hidden> wrote:
Hi,

I've been using the C++ API with Octave 3.6.4 gcc/Mingw for a while without any problems.  I've built a small static library and I know it works on this platform.

I'm now forced (for reasons unrelated to anything here) to compile that same library using MSVC tools.  My library compiles fine for Octave3.6.4/VS2010 but I'm having a problem linking.  Specifically I'm having problems linking to any of the functions defined in xdiv.h.

To demonstrate the problem I'm having, I tried compiling the simple octfile code below (which was taken from a post on the forum: https://mailman.cae.wisc.edu/pipermail/help-octave/2010-August.txt).  I used mkoctfile.-v and all the switches/paths look correct.

#include <octave/oct.h>
#include <octave/xdiv.h> DEFUN_DLD( backslash, args, nargout , "-*- texinfo -*-\n\
@deftypefn {Function File} address@hidden = } backslash (@var{A}, @var{b})\n\
Solve a linear system Ax = b. This is just a script to demonstrate how to do it in an octfile, because it's not so obvious...\n\
@end deftypefn\n\
\n\
Author: Stefan Hedman <schteppe@@gmail.com>\n")

octave_value retval; 
if(args.length()!=2)

print_usage(); 
return retval; 
}
Matrix b(args(0).matrix_value()); 
Matrix A(args(1).matrix_value()); 
MatrixType mt(args(1).matrix_value()); 
Matrix x = xleftdiv(b,A,mt); 
return octave_value(x);
}

This code compiles and links fine using mkoctfile on Octave 3.6.4/mingw (binaries downloaded from sourceforge), but when compiled using mkoctfile on Octave 3.6.4/VS2010 (binaries also from sourceforge), I get the following linker error:

backslash.o : error LNK2019: unresolved external symbol "class Matrix __cdecl xleftdiv(class Matrix const &,class Matrix t &,class MatrixType &,enum blas_trans_type)" (?xleftdiv@@YA? VMatrix@@address@hidden@@W4blas_trans_type@@@Z) refer in function "class octave_value_list __cdecl Fbackslash(class octave_value_list const &,int)" (?Fbackslash@@YA?AVoctave e_list@@address@hidden@Z)
backslash.oct : fatal error LNK1120: 1 unresolved externals


I'm pretty sure I've set my environment up correctly, since the code compiles, links and executes without problem on VS2010 platform if I change the xleftdiv() to b*A.  It seems that either 1) all the functions in xdiv.h are not exposed in the octave libs for the VS2010 build, or 2) the _cdecl decoration on xleftdiv() does not match the octave library.  Do either of these causes sound plausible?  I ran dumpbin on octinterp.lib and couldn't find any of the relavant functions (though I could find the relevant handles in liboctinterp.dll.a using nm), so I'm assuming that #1 is the more likely of two possible causes.

Before I look any further into this, does anyone know if the functions in xdiv.h are exposed in the VS2010 build on sourceforge, and if so in which lib file are they exposed? I've reached the extent of my skills here and thought I would ask before spending more time on this.

The functions you're looking for are not exposed in the DLL. To expose them, they should be decorated with OCTINTERP_API. There's no clear definition of the octave API, so functions are not systematically decorated. The decorator have been added so that octave can compile with MSVC, along with its oct-files and a bunch of forge packages.

If those functions can be considered as part of the API, then the decorator can be added. But this would require recompiling octave. So at the moment, I'm afraid you're a bit dead in the water. The problem does not occur with MinGW, because it's able to auto-export all symbols. MSVC is not.

Michael.




_______________________________________________
Help-octave mailing list
address@hidden
https://mailman.cae.wisc.edu/listinfo/help-octave





reply via email to

[Prev in Thread] Current Thread [Next in Thread]