Hi,
I'm trying to use the AMD math libraries for BLAS (version 4.3.0) combined with the PLASMA library. I've included my compiler and linker settings along with the error output from the compiler. The source is also included at the bottom.
I am trying to build a simple console application on windows xp using Visual studio v 2008. I'd like to make a solution (.sln file) rather than use a makefile. I've studied the example makefile and tried to duplicate it but no success. I've tried many variations of link and compile options. In my latest attempt the compiler settings are:
/Od /I "..\..\Plasma\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /Gm /EHsc /RTC1 /MT /Yu"stdafx.h" /Fp"Debug\TestPLASMA.pch" /Fo"Debug\\" /Fd"Debug\vc90.pdb" /W3 /nologo /c /ZI /TP /errorReport:prompt
and the latest link options are:
/OUT:"D:\Andy\CCProjects\TestPLASMA\Debug\TestPLASMA.exe" /INCREMENTAL /NOLOGO /LIBPATH:"../../Plasma/lib" /LIBPATH:"../../AMD/acml4.3.0/ifort32/lib" /MANIFEST /MANIFESTFILE:"Debug\TestPLASMA.exe.intermediate.manifest" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /NODEFAULTLIB:"MSVCRT.lib" /NODEFAULTLIB:"MSVCRTd.lib" /DEBUG /PDB:"D:\Andy\CCProjects\TestPLASMA\Debug\TestPLASMA.pdb" /SUBSYSTEM:CONSOLE /DYNAMICBASE /NXCOMPAT /MACHINE:X86 /ERRORREPORT:PROMPT libacml.lib libmmd.lib plasma.lib coreblas.lib cblas.lib corelapack.lib libirc.lib libmmt.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib
the compile errors are:
1>------ Build started: Project: TestPLASMA, Configuration: Debug Win32 ------
1>Linking...
1>LINK : warning LNK4075: ignoring '/INCREMENTAL' due to '/FORCE' specification
1>LINK : warning LNK4098: defaultlib 'LIBCMT' conflicts with use of other libs; use /NODEFAULTLIB:library
1>libacml.lib(acmlmallocc.obj) : warning LNK4217: locally defined symbol _malloc imported in function _acmlmallocc_
1>libacml.lib(acmlcpuid.obj) : warning LNK4217: locally defined symbol _malloc imported in function _acmlcpuid
1>libacml.lib(acmlmallocc.obj) : warning LNK4217: locally defined symbol _free imported in function _acmlfreec_
1>libacml.lib(acmlcpuid.obj) : warning LNK4049: locally defined symbol _free imported
1>libacml.lib(acmlcpuid.obj) : warning LNK4217: locally defined symbol _strncmp imported in function _GetCacheInfo
1>libacml.lib(acmlcpuid.obj) : warning LNK4217: locally defined symbol _fprintf imported in function _PrintTLBTYPE
1>libacml.lib(acmlcpuid.obj) : warning LNK4217: locally defined symbol _printf imported in function _PrintTLBTYPE
1>TestPLASMA.obj : error LNK2019: unresolved external symbol _dlarnv referenced in function _wmain
1>TestPLASMA.obj : error LNK2019: unresolved external symbol _dlange referenced in function "int __cdecl check_solution(int,int,int,double *,int,double *,double *,int)" (?check_solution@@YAHHHHPANH00H@Z)
1>libcpmtd.lib(xdebug.obj) : error LNK2019: unresolved external symbol __malloc_dbg referenced in function "void * __cdecl operator new(unsigned int,struct std::_DebugHeapTag_t const &,char *,int)" (??2@YAPAXIABU_DebugHeapTag_t@std@@PADH@Z)
1>libcpmtd.lib(xdebug.obj) : error LNK2019: unresolved external symbol __free_dbg referenced in function "void __cdecl operator delete(void *,struct std::_DebugHeapTag_t const &,char *,int)" (??3@YAXPAXABU_DebugHeapTag_t@std@@PADH@Z)
1>D:\Andy\CCProjects\TestPLASMA\Debug\TestPLASMA.exe : fatal error LNK1120: 4 unresolved externals
1>Build log was saved at "file://d:\Andy\CCProjects\TestPLASMA\Debug\BuildLog.htm"
1>TestPLASMA - 5 error(s), 9 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Can you help me?
Possibly a simple .sln file with the steps taken to create it would be most helpful. It would be nice if that was in the installation.
Thanks,
Andrew Roberts
============================================================================
============================================================================
My source file is copied from your an in the install. Here it is:
====================================
// TestPLASMA.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <cblas.h>
#include <plasma.h>
#include "../src/lapack.h"
#ifndef max
#define max(a, b) ((a) > (b) ? (a) : (b))
#endif
#ifndef min
#define min(a, b) ((a) < (b) ? (a) : (b))
#endif
int check_solution(int, int, int, double*, int, double*, double*, int);
int IONE=1;
int ISEED[4] = {0,0,0,1}; /* initial seed for dlarnv() */
int _tmain(int argc, _TCHAR* argv[])
{
//example copied from example_dgels.c
int cores = 2;
int M = 15;
int N = 10;
int LDA = 15;
int NRHS = 5;
int LDB = 15;
int K = min(M, N);
int info;
int info_solution;
int i,j;
int LDAxN = LDA*N;
int LDBxNRHS = LDB*NRHS;
double *A1 = (double *)malloc(LDA*N*sizeof(double));
double *A2 = (double *)malloc(LDA*N*sizeof(double));
double *B1 = (double *)malloc(LDB*NRHS*sizeof(double));
double *B2 = (double *)malloc(LDB*NRHS*sizeof(double));
double *T;
/* Check if unable to allocate memory */
if ((!A1)||(!A2)||(!B1)||(!B2)){
printf("Out of Memory \n ");
exit(0);
}
/* Plasma Initialization */
PLASMA_Init(cores);
printf("-- PLASMA is initialized to run on %d cores. \n",cores);
/* Allocate T */
PLASMA_Alloc_Workspace_dgels(M, N, &T);
/* Initialize A1 and A2 */
dlarnv(&IONE, ISEED, &LDAxN, A1);
for (i = 0; i < M; i++)
for (j = 0; j < N; j++)
A2[LDA*j+i] = A1[LDA*j+i] ;
/* Initialize B1 and B2 */
dlarnv(&IONE, ISEED, &LDBxNRHS, B1);
for (i = 0; i < M; i++)
for (j = 0; j < NRHS; j++)
B2[LDB*j+i] = B1[LDB*j+i] ;
/* PLASMA DGELS */
info = PLASMA_dgels(PlasmaNoTrans, M, N, NRHS, A2, LDA, T, B2, LDB);
/* Check the solution */
info_solution = check_solution(M, N, NRHS, A1, LDA, B1, B2, LDB);
if ((info_solution != 0)|(info != 0))
printf("-- Error in DGELS example ! \n");
else
printf("-- Run of DGELS example successful ! \n");
free(A1); free(A2); free(B1); free(B2); free(T);
PLASMA_Finalize();
exit(0);
return 0;
}
/*--------------------------------------------------------------
* Check the solution
*/
int check_solution(int M, int N, int NRHS, double *A1, int LDA, double *B1, double *B2, int LDB)
{
int info_solution;
double Rnorm, Anorm, Xnorm, Bnorm;
char norm='I';
double alpha, beta;
double *work = (double *)malloc(max(M, N)* sizeof(double));
double eps;
eps = dlamch("Epsilon");
alpha = 1.0;
beta = -1.0;
Anorm = dlange(&norm, &M, &N, A1, &LDA, work);
Xnorm = dlange(&norm, &M, &NRHS, B2, &LDB, work);
Bnorm = dlange(&norm, &N, &NRHS, B1, &LDB, work);
cblas_dgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, M, NRHS, N, (alpha), A1, LDA, B2, LDB, (beta), B1, LDB);
if (M >= N) {
double *Residual = (double *)malloc(M*NRHS*sizeof(double));
memset((void*)Residual, 0, M*NRHS*sizeof(double));
cblas_dgemm(CblasColMajor, CblasTrans, CblasNoTrans, N, NRHS, M, (alpha), A1, LDA, B1, LDB, (beta), Residual, M);
Rnorm = dlange(&norm, &M, &NRHS, Residual, &M, work);
free(Residual);
}
else {
double *Residual = (double *)malloc(N*NRHS*sizeof(double));
memset((void*)Residual, 0, N*NRHS*sizeof(double));
cblas_dgemm(CblasColMajor, CblasTrans, CblasNoTrans, N, NRHS, M, (alpha), A1, LDA, B1, LDB, (beta), Residual, N);
Rnorm = dlange(&norm, &N, &NRHS, Residual, &N, work);
free(Residual);
}
printf("============\n");
printf("Checking the Residual of the solution \n");
printf("-- ||Ax-B||_oo/((||A||_oo||x||_oo+||B||)_oo.N.eps) = %e \n",Rnorm/((Anorm*Xnorm+Bnorm)*N*eps));
if (isnan(Rnorm / ((Anorm * Xnorm + Bnorm) * N * eps)) || (Rnorm / ((Anorm * Xnorm + Bnorm) * N * eps) > 10.0) ) {
printf("-- The solution is suspicious ! \n");
info_solution = 1;
}
else {
printf("-- The solution is CORRECT ! \n");
info_solution= 0 ;
}
free(work);
return info_solution;
}
