Skip to content

cblas: compatibility for compilers without C99 complex number support (e.g. Visual Studio) #95

@zchothia

Description

@zchothia

Hello Xianyi,

Visual Studio is unable to compile <cblas.h> included with OpenBLAS, due to its
use of the _Complex type which assumes C99 support. Here is a patch which switches
to a binary-compatible structure in cases where the complex number type is not available: https://gist.github.com/2470335.

With this change in place, this test program can now be built with Visual Studio 2010:

#include <stdio.h>

#include <openblas/cblas.h>

int main(void) {
  int N = 2, incX = 1, incY = 1;
  double x[] = {1.0, 2.0, 3.0, 4.0};
  double y[] = {1.0, 2.0, 3.0, 4.0};
  openblas_complex_double result = cblas_zdotu(N, x, incX, y, incY);
  printf("result = %lf + %lfi\n", openblas_complex_double_real(result),
                                  openblas_complex_double_imag(result));
  // Expected output: -10.000000 + 28.000000i
  return 0;
}

I have tested this change on Linux and Windows (MinGW) and have not observed any adverse effects.

Best,

--Zaheer

Additional notes:

  • <f77blas.h> has the same issue, but already contains a workaround, so I didn't make any changes.

  • The approach I have used is similar to that used in LAPACKE (see <lapacke_config.h>).
    There are several utility routines (make_complex, *_real, *_imag) included, which
    are not strictly necessary, but permit writing code which works with either complex type.

    It should be noted that OPENBLAS_COMPLEX_STRUCT is not a drop-in replacement
    for OPENBLAS_COMPLEX_C99. For instance, this snippet works with C99's _Complex,
    but fails to compile with the struct form:

    openblas_complex_double z1 = openblas_make_complex_double(1.0, 2.0);
    openblas_complex_double z2 = openblas_make_complex_double(3.0, 4.0);
    openblas_complex_double z3 = z1 + z2;

    For this reason, it may be preferrable to entirely drop the C99 _Complex type and
    always use the struct form, leaving conversion to client code. This is the approach
    taken by Intel's MKL, which is described in more detail here.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions