一个简单的使用MKL的例子

intel_cyu 2008-04-07 11:31:45
下面是一个使用Intel MKL 进行矩阵计算的例子。 通过的这个例子,我们可以了解如何使用Intel MKL 的函数库:

1>程序说明:下面的matrix.c 文件分别调用 C 代码,Intel MKL BLAS Level 1 函数 (ddot), BLAS Level 2 函数(dgemv) 与 BLAS Level 3的函数(DGEMM)完成矩阵计算: roll_your_own_multiply 是 C 源代码,它直接依赖编译器生成优化代码。Ddot_Multiply,Dgemv_multiply使用Intel MKL 函数实现部分矩阵运算。Dgemm_multiply 直接调用MKL 的矩阵计算函数。

2>程序编译与链接:


下面是在Linux 32 的系统上,使用Intel Compiler编译该程序并链接Intel MKL 10.0的例子:
> source /opt/intel/cc/10.x.xxx/bin/iccvars.sh #设置Intel Compiler 环境变量
> icl –o matrix –I/opt/intel/mkl/10.0.xxxxx/include/ matrix.c-L/opt/intel/mkl/10.0.xxxx/lib/32/ -lmkl_intel_c -lmkl_intel_thread -lmkl_core -lguide40.lib –lpthread

其他的链接的方式,大家可以查看下面的帖子:http://support.intel.com/support/performancetools/sb/CS-028699.htm

3> 程序执行:
> source /opt/intel/mkl/10.0.xxxxx/tools/environment/mklvars32.sh #程序使用动态方式链接MKL函数时,设置MKL的环境变量。
>./matrix

4> 设置多线程运行:在Intel MKL 10.0 使用OpenMP* 实现多线程。 OpenMP*程序可以通过环境变量 OMP_NUM_THREADS 去控制线程的数目。
> export OMP_NUM_THRADS=4 #设置程序的线程为 4
> ./matrix #DGEMM在执行的时候使用4个线程。

注意:在MKL 10.0 中, 如果OMP_NUM_THREADS没有定义,MKL函数可能会根据数据的大小,以及其他的变量来设置线程数目, 缺省时,可能运行多个线程运行。

源程序下载的URL:
http://download355.mediafire.com/p59lw9bldalg/g2shflsx1md/testcode.c
...全文
3213 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
goodbeybey 2011-02-22
  • 打赏
  • 举报
回复
开始学习 mkl
laxila 2008-09-30
  • 打赏
  • 举报
回复
非常好,学习过了,谢谢楼主呀!!!
majiajun_no_5 2008-09-30
  • 打赏
  • 举报
回复
获益匪浅
majiajun_no_2 2008-09-29
  • 打赏
  • 举报
回复
我同意 支持一下
majiajun_no_13 2008-09-28
  • 打赏
  • 举报
回复
潜水多年,今日上岸,继续学习
chriswyg 2008-09-26
  • 打赏
  • 举报
回复
感谢楼主,最近正在研究MKL,呵呵
intel_iclifort 2008-06-06
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 youxia000 的回复:]
MKL 不能在windows下用么?

他的使用和IPP一样么?包含进来然后就可以调用函数的方式?


[/Quote]

MKL 有 Windows 版本, 它也是采用通过函数API调用库的形式, 一般适合矩阵规模较大的场合
youxia000 2008-06-06
  • 打赏
  • 举报
回复
MKL 不能在windows下用么?

他的使用和IPP一样么?包含进来然后就可以调用函数的方式?

yanite2008 2008-04-20
  • 打赏
  • 举报
回复
该贴已经过期
intel_cyu 2008-04-20
  • 打赏
  • 举报
回复
下面是例子代码:

//Simple minded matrix multiply
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include "mkl.h"

void print_arr(int N, char * name, double* array);
void init_arr(int N, double* a);
void Dgemm_multiply(double* a,double* b,double* c, int N);
void Dgemv_multiply(double* a,double* b,double* c, int N);
void Ddot_Multiply(double* a,double* b,double* c, int N);
void roll_your_own_multiply(double* a,double* b,double* c, int N);

int main(int argc, char* argv[])
{
clock_t start, stop;
int i, j;
int N;
double* a;
double* b;
double* c;
if(argc < 2)
{
printf("Enter matrix size N=");
//please enter small number first to ensure that the
//multiplication is correct! and then you may enter
//a "reasonably" large number say like 500 or even 1000
scanf("%d",&N);
}
else
{
N = atoi(argv[1]);
}

a=(double*) malloc( sizeof(double)*N*N );
b=(double*) malloc( sizeof(double)*N*N );
c=(double*) malloc( sizeof(double)*N*N );

init_arr(N,a);
init_arr(N,b);

start = clock();
roll_your_own_multiply(a,b,c,N);
stop = clock();
printf("roll_your_own_multiply(). Elapsed time = %g seconds\n",
((double)(stop - start)) / CLOCKS_PER_SEC);
//print simple test case of data to be sure multiplication is correct
if (N < 7) {
print_arr(N,"a", a);
print_arr(N,"b", b);
print_arr(N,"c", c);
}
free(a);
free(b);
free(c);

//DDOT multiply
a=(double*) malloc( sizeof(double)*N*N );
b=(double*) malloc( sizeof(double)*N*N );
c=(double*) malloc( sizeof(double)*N*N );
init_arr(N,a);
init_arr(N,b);


start = clock();
Ddot_Multiply(a,b,c,N);
stop = clock();

printf("Ddot_Multiply(). Elapsed time = %g seconds\n",
((double)(stop - start)) / CLOCKS_PER_SEC);
//print simple test case of data to be sure multiplication is correct
if (N < 7) {
print_arr(N,"a", a);
print_arr(N,"b", b);
print_arr(N,"c", c);
}
free(a);
free(b);
free(c);



//DGEMV Multiply
//reallcoate to force cash to be flushed
a=(double*) malloc( sizeof(double)*N*N );
b=(double*) malloc( sizeof(double)*N*N );
c=(double*) malloc( sizeof(double)*N*N );
init_arr(N,a);
init_arr(N,b);

start = clock();
Dgemv_multiply(a,b,c,N);
stop = clock();

printf("Dgemv_multiply(). Elapsed time = %g seconds\n",
((double)(stop - start)) / CLOCKS_PER_SEC);
//print simple test case of data to be sure multiplication is correct
if (N < 7) {
print_arr(N,"a", a);
print_arr(N,"b", b);
print_arr(N,"c", c);
}
free(a);
free(b);
free(c);


//DGEMM Multiply
//reallocate to force cash to be flushed
a=(double*) malloc( sizeof(double)*N*N );
b=(double*) malloc( sizeof(double)*N*N );
c=(double*) malloc( sizeof(double)*N*N );
init_arr(N,a);
init_arr(N,b);

start = clock();
Dgemm_multiply(a,b,c,N);
stop = clock();

printf("Dgemm_multiply(). Elapsed time = %g seconds\n",
((double)(stop - start)) / CLOCKS_PER_SEC);
//print simple test case of data to be sure multiplication is correct
if (N < 7) {
print_arr(N,"a", a);
print_arr(N,"b", b);
print_arr(N,"c", c);
}

free(a);
free(b);
free(c);

return 0;
}

//Brute force way of matrix multiply
void roll_your_own_multiply(double* a,double* b,double* c, int N)
{
int i, j, k;
for (i = 0; i < N; i++) {
for (j=0; j<N; j++) {
for (k=0; k<N; k++) {
c[N*i+j] += a[N*i+k] * b[N*k+j];
}
}
}
}

//The ddot way to matrix multiply
void Ddot_Multiply(double* a,double* b,double* c, int N)
{
int i, j;
int incx = 1;
int incy = N;
for (i = 0; i < N; i++) {
for (j=0; j<N; j++) {
c[N*i+j] = cblas_ddot(N,&a[N*i],incx,&b[j],incy);
}
}
}
//DGEMV way of matrix multiply
void Dgemv_multiply(double* a,double* b,double* c, int N)
{
int i;
double alpha = 1.0, beta = 0.;
int incx = 1;
int incy = N;
for (i = 0; i < N; i++) {
cblas_dgemv(CblasRowMajor,CblasNoTrans,N,N,alpha,a,N,&b[i],N,beta,&c[i],N);

}
}

//DGEMM way. The PREFERED way, especially for large matrices
void Dgemm_multiply(double* a,double* b,double* c, int N)
{
int i;
double alpha = 1.0, beta = 0.;
int incx = 1;
int incy = N;
cblas_dgemm(CblasRowMajor,CblasNoTrans,CblasNoTrans,N,N,N,alpha,b,N,a,N,beta,c,N);
}

//initialize array with random data
void init_arr(int N, double* a)
{
int i,j;
for (i=0; i< N;i++) {
for (j=0; j<N;j++) {
a[i*N+j] = (i+j+1)%10; //keep all entries less than 10. pleasing to the eye!
}
}
}

//print array to std out
void print_arr(int N, char * name, double* array)
{
int i,j;
printf("\n%s\n",name);
for (i=0;i<N;i++){
for (j=0;j<N;j++) {
printf("%g\t",array[N*i+j]);
}
printf("\n");
}
}




566

社区成员

发帖
与我相关
我的任务
社区描述
英特尔® 边缘计算,聚焦于边缘计算、AI、IoT等领域,为开发者提供丰富的开发资源、创新技术、解决方案与行业活动。
社区管理员
  • 英特尔技术社区
  • shere_lin
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧