exptern “C“的作用,在 C 和 CPP 中分别调用 openblas 中的 gemm 为例

news2024/9/27 14:46:33

 openblas提供的sgemm有两种方式,一种是通过cblas,另一种是直接声明并调用 sgemm_

其中,cblas方式是更正规调用方法;

1,调用openblas的 sgemm 的两种方式

1.1 c语言程序中使用 sgemm

hello_sgemm.c

#include <stdlib.h>
#include <stdio.h>

//#define CBLAS_USE 1 


#ifdef CBLAS_USE
#include "cblas.h"
#else
//extern "C"{
	void sgemm_( char * const transpa,  char * const transpb, int *m, int *n,
        	      int *k, float *alpha, float *a, int *lda, float *b, int *ldb,
              		float *beta, float *c, int *ldc );
//}
#endif

void init_matrix(int M, int N, float* A, int lda, int seed)
{
	srand(seed);
	for(int i=0; i<M; i++){
		for(int j=0; j<N; j++){
			A[i + j*lda] = (float)rand()/RAND_MAX;
		}
	}
}

void print_matrix(int M, int N, float* A, int lda)
{
	for(int i=0; i<M; i++){
		for(int j=0; j<N; j++){
			printf(" %7.4f ", A[i + j*lda]);
		}
	printf("\n");
	}
}

int main()
{
	int M = 3;
	int N = 3;
	int K = 3;

	float* A = NULL;
	float* B = NULL;
	float* C = NULL;
	int lda = M;
	int ldb = K;
	int ldc = M;

	A = (float*)malloc(lda*K* sizeof(float));
	B = (float*)malloc(ldb*N* sizeof(float));
	C = (float*)malloc(ldc*N* sizeof(float));

	init_matrix(M, K, A, lda, 2023);	printf("\nA =\n"); 	print_matrix(M, K, A, lda);
	init_matrix(K, N, B, ldb, 2024);	printf("\nB =\n");	print_matrix(K, N, B, ldb);
	init_matrix(M, N, C, ldc, 2025);	printf("\nC =\n");	print_matrix(M, N, C, ldc);


	float alpha = 1.0f;
	float beta = 0.0f;
#ifdef CBLAS_USE
	cblas_sgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, M, N, K, 1.0, A, lda, B, ldb, 0.0, C, ldc);
	printf("C = alpha*A*B + beta*C =cblas_sgemm()=\n");	print_matrix(M, N, C, ldc);
#else
	sgemm_("N", "N", &M, &N, &K, &alpha, A, &lda, B, &ldb, &beta, C, &ldc);
	printf("C = alpha*A*B + beta*C = sgemm_()=\n");	print_matrix(M, N, C, ldc);
#endif

	return 0;
}

运行效果:

$ gcc -DCBLAS_USE  hello_sgemm.c -L ../tdd/third-party/openblas/local/lib/ -lopenblas -o hello_sgemm_c

$ gcc  hello_sgemm.c -L ../tdd/third-party/openblas/local/lib/ -lopenblas -o hello_sgemm_c

 

可见调用 sgemm_() 与调用 cblas_sgemm() 的结果相同;

需要注意sgemm_()函数的声明方式,参数全部都是指针:

void sgemm_( char * const transpa,  char * const transpb, int *m, int *n,
                  int *k, float *alpha, float *a, int *lda, float *b, int *ldb,
                      float *beta, float *c, int *ldc );

1.2 cpp 语言程序中调用 sgemm

相较于 c 语言中,cpp 程序中增加了 extern "C"{ 修饰;

否则编译无法通过,由于c++的特性。

hello_sgemm.cpp

#if CBLAS_USE
#include "cblas.h"
#else
extern "C"{
	void sgemm_( char * const transpa,  char * const transpb, int *m, int *n,
        	      int *k, float *alpha, float *a, int *lda, float *b, int *ldb,
              		float *beta, float *c, int *ldc );
}
#endif

 

2. cpp 中的sgemm_声明为何需要 extern "C"

extern "C" 的作用:

       在 C++ 源代码文件中,使用 extern "C" 的作用是告诉编译器按照 C 语言的方式对函数进行链接,而不是 C++ 的方式。这在与其他语言或库进行交互时非常有用,特别是在 C++ 代码中调用 C 语言编写的函数时。


        当您使用 extern "C" 修饰一个函数声明时,编译器会按照 C 语言的命名约定来生成函数符号,这样可以确保 C++ 代码和 C 代码之间的函数调用能够正确链接。在 C++ 中,函数名可能会经过名称修饰(name mangling)以支持函数重载和其他特性,比如在函数末尾加上参数类型缩写,而 C 语言没有这种面向对象的语法概念和需求。

如下图可见,

print_matrix函数的名字,在 cpp中被加了前缀和后缀,而 c语言文件中,函数名字依然为

print_matrix

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1985334.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

层次分析法(评价类问题)

本文章内容来自&#xff1a;​​​​​​​ 层次分析法模型讲解(附matlab和python代码) 【数学建模快速入门】数模加油站 江北_哔哩哔哩_bilibili 一. 概念 做决策依托于量化分析&#xff0c;量化分析依托于选择的指标以及各项指标的权重&#xff08;重要性及对结果的影响程度…

XLT开关矩阵

开关矩阵 苏州新利通 系列化开关矩阵是提高被测件测试效率、实现自动化测试的核心设备&#xff0c;是基于标准控制平台可进行定制化设计的产品。系列化开关矩阵工作频率范围覆盖DC~67GHz&#xff0c;可通过LAN、GPIB、RS232和USB-B等标准控制接口&#xff0c;支持客户端、Web…

ElasticSearch安装与集群部署

ElasticSearch安装与集群部署 很多小伙伴第一次接触ElasticSearch的时候是一脸愁容,这个东西他怎么用啊,不知道从哪里安装,那我们今天就着重从哪里下载?怎么下载?怎么安装?来研究一下吧! windows下载安装ElasticSearch 下载地址&#xff1a;https://www.elastic.co/cn/do…

移动端下拉加载更多(h5,小程序)

1.h5,使用原生方式监听页面滚动下拉加载更多 <template><div></div> </template><script> export default {data() {return {loadflag: true,maxpages: 0, //最大页码currentpage: 0, //当前页listData: [],config: {page: 1,pageSize: 15,tota…

Unity开发的Domino多米诺3D小游戏源码

Unity开发的Domino多米诺3D小游戏源码下载地址

计算机组成原理 - 总线、输入/输出系统

总线 考纲内容 总线的基本概念总线的组成及性能指标总线事务和定时 本章大多以选择题的形式出现&#xff0c;特别是总线的特点、猝发传输方式、性能指标、定时方式及常见的总线标准等 思考以下问题&#xff1a; 1、引入总线结构有什么好处? 2、引入总线结构会导致什么问题…

公司官网为何建议用OV SSL证书?如何申请?

随着网络安全威胁的日益增多&#xff0c;保护用户数据安全变得尤为重要。其中SSL&#xff08;Secure Sockets Layer&#xff09;证书成为了保障网站安全的关键技术之一。而在众多SSL证书中&#xff0c;OV&#xff08;Organization Validation&#xff09;SSL证书因其独特的优势…

JVM(九)深入解析Java字节码技术与执行模型

这篇文章深入探讨了Java字节码技术&#xff0c;包括字节码的简介、获取字节码清单的方法、解读字节码清单、查看class文件中的常量池信息、查看方法信息、线程栈与字节码执行模型、方法体中的字节码解读、对象初始化指令、栈内存操作指令、局部变量表、流程控制指令、算术运算指…

读取压缩文件

读取压缩文件 1、背景 D盘下面有一个zipTest1.zip压缩文件 1.1 zipTest里面的内容 1.2 zipTest中有三个文件夹dir1、dir2、dir3 1.3 每一个文件夹下都有一个.txt文件 2、要求 读取D盘下面zipTest1.zip压缩文件里的内容到D盘下面zipTest2 3、实现 public static void main…

Go语言使用cobra开发第一个命令行程序

源码下载 本教程源码下载地址&#xff1a;https://github.com/zhangdapeng520/zdpgo_cobra_examples 案例说明 实现一个简单的命令行程序&#xff0c;能够将输入的单词转换为大写。 使用演示 执行命令&#xff1a; go run .\main.go word -u -s hello输出结果&#xff1a…

XXE靶机教学

arp-scan -l主机发现 arp-scan -l 端口扫描 nmap -p- 192.168.48.139 服务探测 nmap -p80,5355 -sT -sC -sV 192.168.48.139 目录扫描 dirsearch -u http://192.168.48.139 访问robots.txt 发现两个可访问路径 burp抓包 测试是否存在xxe漏洞 <?xml version "1.…

超声波清洗机性价比高的型号有哪些?四款值得关注的高性能超声波清洗机推荐

如果你发现眼镜变得非常脏&#xff0c;甚至出现青铜色的污渍&#xff0c;那说明是时候清洁眼镜了&#xff01;很多人往往不在意这些细节&#xff0c;结果眼镜越戴越模糊&#xff0c;实际上这主要是因为镜片上的油污、手指皮肤的残留以及生活中的灰尘积累。如果不及时清洁&#…

【实现100个unity特效之15】最简单的方法使用shader graphs实现2d树叶草的随风摇摆效果

文章目录 前言新建shader graphs新建材质效果完结 前言 本文只是实现一个简单版本的2d树叶草随风摇摆的效果&#xff0c;如果你想要实现更加复杂的效果&#xff0c;包括2d互动草&#xff0c;你可以参考我之前的文章&#xff1a; 【推荐100个unity插件之24】实现2d交互式草树叶…

瑞熙贝通智慧库房物料管理系统v3.0

一、系统介绍 智慧库房物料软件是库房全流程管理中的管理方式&#xff0c;为强化库房在各个环节管理&#xff0c;提高库房物料管理的效率&#xff0c;针对库房物料管理中存在的问题&#xff0c;瑞熙贝通在库房物料管理工作等方面不断创新&#xff0c;在制度建设、管理流程设计…

2024,Java开发在中国市场还有发展前景吗?

随着2024年的到来&#xff0c;Java作为一种经典而强大的编程语言&#xff0c;依然在中国的软件开发市场中扮演着重要角色。然而&#xff0c;许多人对Java的未来发展前景持有不同的看法。让我们来探讨一下当前情况和未来的走向。 Java程序员真的过剩了吗&#xff1f; 2023年, 各…

深度学习 —— 个人学习笔记14(ResNet、DenseNet)

声明 本文章为个人学习使用&#xff0c;版面观感若有不适请谅解&#xff0c;文中知识仅代表个人观点&#xff0c;若出现错误&#xff0c;欢迎各位批评指正。 二十八、残差网络&#xff08; ResNet &#xff09; import torch import torchvision import time from torch impo…

01:PID

前言 位式控制算法 位式控制算法是一种通过比较设定值&#xff08;SV&#xff09;和当前值&#xff08;PV&#xff09;来控制目标的方法。当PV小于SV时&#xff0c;输出高电平&#xff0c;执行部件工作&#xff1b;当PV大于或等于SV时&#xff0c;输出低电平&#xff0c;执行部…

Android 中compileSdk、minSdk、targetSdk 是干什么用的?

作为多年 Android 开发的老司机&#xff0c; compileSdk 、minSdk、targetSdk 都是经常见到&#xff0c;但其具体含义是什么&#xff1f;它们都是在什么场景下去使用的。回想起来还真不太能说得清楚。 背景 要想说清楚它们是干什么的&#xff0c;那就不得不说一下主角 Android …

每组中随机选一行

Excel的A列是分组&#xff0c;B列是明细。 AB1GroupName2AJohn3AJoe4AAnn5ASusan6AJames7AMary8AL .orraine9BJoseph10BSinead11BMichelle12BBreege13BTom14BFrancis15BConan16BCait17BRonan18BDeirdre19BAoife20BSile21BSarah22CLisa23CMicky24CPat25DMiles26DOlivia27DAvril…

骑行合并 轨迹合并

https://gpxt.beer5214.com/ 利用GPX轨迹合并工具提升长途骑行与徒步体验 对于长途骑行或长途徒步旅行的爱好者来说&#xff0c;记录和管理GPS轨迹是一项重要的活动。无论是为了后续分析自己的路线、分享经历还是为下一次冒险做准备&#xff0c;确保所有轨迹数据的完整性和连贯…