Skip to content

cheevd_ has wrong results when compiled with MSVC on Ryzen AI Max+ #5562

@AGonzales-amd

Description

@AGonzales-amd

Version: Tested on v0.3.30 & develop branch.

Host: AMD Ryzen AI Max+ 395

Build: Visual Studio x64 Native Tools cmd prompt, cmake, ninja

Flags: -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DC_LAPACK=ON -DTARGET=HASWELL -DDYNAMIC_ARCH=OFF -DBUILD_TESTING=OFF -DNOFORTRAN=1

cheevd returns different results when linking to an openblas.dll compiled with MSVC compiler compared to a prebuilt binary or compiling with mingw64.
Results:

  • v0.3.30 prebuilt binary: W={ 361.063, 381.069, 385.608, 393.389, 398.055, 405.462, 409.183, 415.139, 416.879, 422.932, 427.312, 460.909 }
  • mingw64: W={ 361.063, 381.069, 385.608, 393.389, 398.056, 405.462, 409.183, 415.139, 416.88, 422.932, 427.312, 460.909 }
  • MSVC: W={ -166.679, -70.1807, 1.43707, 84.1033, 140.193, 226.399, 265.468, 302.804, 348.698, 370.388, 382.994, 411.005 }

Steps to reproduce:

Build OpenBLAS

  1. git clone https://github.com/OpenMathLib/OpenBLAS.git
  2. cd OpenBLAS
  3. compile library files
    a. MSVC:
    cmake.exe -GNinja -B build -S . -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DC_LAPACK=ON -DTARGET=HASWELL -DDYNAMIC_ARCH=OFF -DBUILD_TESTING=OFF -DNOFORTRAN=1 -DCMAKE_C_COMPILER=cl -DCMAKE_CXX_COMPILER=cl
    b. mingw64:
    cmake.exe -GNinja -B build -S . -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DC_LAPACK=ON -DTARGET=HASWELL -DDYNAMIC_ARCH=OFF -DBUILD_TESTING=OFF -DNOFORTRAN=1 -DCMAKE_C_COMPILER=cc -DCMAKE_CXX_COMPILER=c++
  4. cmake --build build

Build reproducer

  1. cl test_heevd.cpp <path\to\lib>\libopenblas.lib
  2. .\test_heevd.exe

Reproducer (test_heevd.cpp):

#include <iostream>
#include <ostream>
#include <random>
#include <vector>

#ifdef __cplusplus
extern "C" {
#endif

typedef struct float_complex
{
    float x, y;
} float_complex;

void cheevd_(char* evect,
             char* uplo,
             int* n,
             float_complex* A,
             int* lda,
             float* W,
             float_complex* work,
             int* lwork,
             float* rwork,
             int* lrwork,
             int* iwork,
             int* liwork,
             int* info);


#ifdef __cplusplus
}
#endif

std::ostream& operator<<(std::ostream& os, const float_complex& rhs)
{
    os << "(" << rhs.x << ", " << rhs.y << ")";
    return os;
}

template <typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<T>& rhs)
{
    auto n = rhs.size();

    if(n == 0)
        return os;

    os << "{ " << rhs[0];
    for(int64_t i = 1; i < n; ++i)
    {
        os << ", " << rhs[i];
    }
    os << " }" << std::endl;

    return os;
}

void generate_matrix(int n, int lda, float_complex* mtx)
{
    std::mt19937 engine(69069);
    std::uniform_int_distribution<> dist(1, 10);
    for(int j = 0; j < n; j++)
    {
        for(int i = 0; i < n; i++)
        {
            mtx[i + (j * lda)] = {float(dist(engine)), float(dist(engine))};

            if(i == j)
                mtx[i + (j * lda)].x += 400;
            else
                mtx[i + (j * lda)].x -= 4;
        }
    }
}

int main(void)
{
    char evect = 'N';
    char uplo = 'L';
    int n = 12;
    int lda = n;
    std::vector<float_complex> A(n * lda, {0, 0});
    std::vector<float> W(n, 0);

    int sizeE  = (evect == 'N' ? n : 1 + 5 * n + 2 * n * n);
    int ltwork = (evect == 'N' ? n + 1 : 2 * n + n * n);
    int liwork = (evect == 'N' ? 1 : 3 + 5 * n);

    std::vector<float_complex> work(ltwork);
    std::vector<float> hE(sizeE);
    std::vector<int> iwork(liwork);

    int info;

    generate_matrix(n, lda, A.data());

    std::cout << "A before heevd: " << std::endl;
    std::cout << A << std::endl;

    cheevd_(&evect, &uplo, &n, A.data(), &lda, W.data(), work.data(), &ltwork, hE.data(), &sizeE, iwork.data(), &liwork, &info);

    std::cout << "W after heevd: " << std::endl;
    std::cout << W << std::endl;
    return 0;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions