首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 .NET Java 游戏 视频 人才 外包 培训 数据库 书店 程序员
中国软件网
欢迎您:游客 | 登录 注册 帮助
  • 一个简单的使用MKL的例子
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于: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
    20  修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-20 11:58:251楼 得分:0
    该贴已经过期
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-20 21:01:272楼 得分:0
    下面是例子代码:

    //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");
    }
    }


    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-06-06 09:52:463楼 得分:0
    MKL  不能在windows下用么?

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

    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-06-06 10:03:444楼 得分:0
    引用 3 楼 youxia000 的回复:
    MKL  不能在windows下用么?

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




    MKL 有 Windows 版本, 它也是采用通过函数API调用库的形式, 一般适合矩阵规模较大的场合
    修改 删除 举报 引用 回复

    网站简介广告服务网站地图帮助联系方式诚聘英才English 问题报告
    北京创新乐知广告有限公司 版权所有 京 ICP 证 070598 号
    世纪乐知(北京)网络技术有限公司 提供技术支持
    Copyright © 2000-2008, CSDN.NET, All Rights Reserved