首页 > 其他分享 >在CMake中配置使用Intel One API并启用OpenMP(阶段2)

在CMake中配置使用Intel One API并启用OpenMP(阶段2)

时间:2023-11-02 19:23:12浏览次数:43  
标签:std cmake CMake CXX API OpenMP Heroius Intel

本示例尝试使用CMake配置使用Intel One API编译器编译支持OpenMP的程序。

环境

  • Visual Studio 2022 Community with C++ desktop
  • Intel One API 2023.2 with VS intergration
  • CMake 3.27.7

样例

程序代码

OpenMPDemo.cpp
// File: OpenMPDemo.cpp
// Coding: utf-8
#include <iostream>
#include <vector>
#include <cstdlib>
#include <omp.h>
#include <chrono>

void matrix_multiplication(const std::vector<std::vector<double>> &A,
													 const std::vector<std::vector<double>> &B,
													 std::vector<std::vector<double>> &C)
{
	int N = A.size();
	int M = B[0].size();
	int K = A[0].size();

#pragma omp parallel for
	for (int i = 0; i < N; ++i)
	{
		for (int j = 0; j < M; ++j)
		{
			for (int k = 0; k < K; ++k)
			{
				C[i][j] += A[i][k] * B[k][j];
			}
		}
	}
}

void matrix_multiplicationNoMP(const std::vector<std::vector<double>> &A,
															 const std::vector<std::vector<double>> &B,
															 std::vector<std::vector<double>> &C)
{
	int N = A.size();
	int M = B[0].size();
	int K = A[0].size();

	// #pragma omp parallel for
	for (int i = 0; i < N; ++i)
	{
		for (int j = 0; j < M; ++j)
		{
			for (int k = 0; k < K; ++k)
			{
				C[i][j] += A[i][k] * B[k][j];
			}
		}
	}
}

void TestMatrixMultiplication(const std::vector<std::vector<double>> &A,
															const std::vector<std::vector<double>> &B,
															std::vector<std::vector<double>> &C, bool bOpenMP)
{
	// double start_time = omp_get_wtime();
	auto start = std::chrono::high_resolution_clock::now();

	// 执行矩阵乘法
	if (bOpenMP)
		matrix_multiplication(A, B, C);
	else
		matrix_multiplicationNoMP(A, B, C);

	// double end_time = omp_get_wtime();
	auto stop = std::chrono::high_resolution_clock::now();
	auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(stop - start);

	if (bOpenMP)
		std::cout << "Using OpenMP:" << std::endl;
	else
		std::cout << "Bot using OpenMP:" << std::endl;
	std::cout << "Time taken: " << duration.count() / 1000.0 << " seconds." << std::endl;
	// std::cout << "Time taken: " << end_time - start_time << " seconds." << std::endl;
}

int main()
{
	//Heroius: 将维度从2000减小到500,以加快调试
	const int N = 500; // 设置矩阵的维度
	std::vector<std::vector<double>> A(N, std::vector<double>(N));
	std::vector<std::vector<double>> B(N, std::vector<double>(N));
	std::vector<std::vector<double>> C(N, std::vector<double>(N, 0));

// 使用随机数填充矩阵 A 和 B
#pragma omp parallel for
	for (int i = 0; i < N; ++i)
	{
		for (int j = 0; j < N; ++j)
		{
			A[i][j] = rand() / 100.0;
			B[i][j] = rand() / 100.0;
		}
	}

	TestMatrixMultiplication(A, B, C, true);
	TestMatrixMultiplication(A, B, C, false);

	std::cin.get();
	return 0;
}

MakeList

CMakeLists.txt
 # File: CMakeLists.txt
# Heroius: min version of cmake who supports IntelLLVM is 3.25 according to https://www.intel.com/content/www/us/en/docs/dpcpp-cpp-compiler/developer-guide-reference/2023-2/use-cmake-with-the-compiler.html
cmake_minimum_required(VERSION 3.25)

# 指定使用C++11标准
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)

# Set the project name
# Heroius: add CXX parameter to use cpp compiler only, so the c language settings are no longer needed
project(OpenMPDemo CXX)

# Look for Intel oneAPI CMake toolchain files
# find_package shall be called after project command 
find_package(IntelSYCL REQUIRED)

# 指定 C++ 编译器
# Heroius: compilers could only be set in user toolchain file according to https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_COMPILER.html
# Heroius: however the effective settings depands on the cmake generator, see Configure_CMake.bat command line
#set(CMAKE_CXX_COMPILER "C:/Program Files (x86)/Intel/oneAPI/compiler/latest/windows/bin/icpx.exe")
# 指明编译工具链
# Heroius: it is suggested that generator toolset set only in a toolchain file according to https://cmake.org/cmake/help/latest/variable/CMAKE_GENERATOR_TOOLSET.html
# Heroius: however the effective settings depands on the cmake generator, see Configure_CMake.bat command line
#set(CMAKE_GENERATOR_TOOLSET "Intel(R) oneAPI DPC++ Compiler 2023")

# Set executable path
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/bin)

# OpenMP 编译标志
# Heroius: OpenMP flags should be '/Qiopenmp' according to https://www.intel.com/content/www/us/en/docs/oneapi/programming-guide/2023-0/c-c-or-fortran-with-openmp-offload-programming.html
# Heroius: however the find_package() commands will set those flags properly itself
#set(OpenMP_CXX_FLAGS "${OpenMP_CXX_FLAGS} /Qiopenmp")  
# OpenMP 库名称
# Heroius: Their should not be space between symbol 'OpenMP_C_LIB_NAMES' and 'libiomp5'
#set(OpenMP_CXX_LIB_NAMES "${OpenMP_CXX_LIB_NAMES}libiomp5") 
#set(OpenMP_libiomp5_LIBRARY "${OpenMP_CXX_LIB_NAMES}")

# 查找OpenMP库
# Heroius: under this instruction, cmake will call 'c:\Program Files\CMake\share\cmake-3.27\Modules\FindOpenMP.cmake' file, in the lines 605-606 of which, the 'if' command has grammatical error:
# Heroius: the 2nd 'CMAKE_${LANG}_COMPILER_ID' should not enbraced in command: if(CMAKE_${LANG}_COMPILER_ID STREQUAL "Fujitsu" OR ${CMAKE_${LANG}_COMPILER_ID} STREQUAL "IntelLLVM")
# Heroius: notice: back up the file before editing FindOpenMP.cmake with admin privilege!
find_package(OpenMP REQUIRED)

# Add the executable
add_executable(OpenMPDemo OpenMPDemo.cpp)

add_sycl_to_target(TARGET OpenMPDemo SOURCES OpenMPDemo.cpp)

# 如果找到OpenMP库,链接到目标可执行文件
if(OpenMP_CXX_FOUND)
    target_link_libraries(OpenMPDemo OpenMP::OpenMP_CXX)
endif()

Configure脚本

Configure_CMake.bat
 :: 如果存在 Build,删除
if exist Build rd /S /Q Build 
:: 如果不存在 Build,创建
if not exist Build md Build
:: 调用批处理设置 Intel oneAPI 的编译环境
Call "C:\Program Files (x86)\Intel\oneAPI\setvars.bat" intel64 vs2022
Set Lib=%lib%;"C:\Program Files (x86)\Intel\oneAPI\compiler\2023.2.0\windows\compiler\lib\intel64_win"
:: 当前文件夹为 Source,子文件夹 .\Build 为构建目录
:: Heroius: the default cmake generator is 'Visual Studio 17 2022', which is not fully featured.
:: Heroius: it seems the Visual Studio generator allways reset compilers to MSVC.
:: Heroius: the only Intel compiler supports cmake is icx, and the only generator supports icx is ninja according to https://www.intel.com/content/www/us/en/docs/dpcpp-cpp-compiler/developer-guide-reference/2023-2/use-cmake-with-the-compiler.html 
cmake -G Ninja -DCMAKE_CXX_COMPILER=icx  -S . -B .\Build 
pause

编译脚本

Build_CMake.bat
 :: 调用批处理设置 Intel oneAPI 的编译环境
:: Heroius: enable basic environments to make sure the std libs could be found
Call "C:\Program Files (x86)\Intel\oneAPI\setvars.bat" intel64 vs2022
:: Set MPI compiler environment
Call "C:\Program Files (x86)\Intel\oneAPI\mpi\Latest\env\vars.bat"
:: 进入构建目录
cd Build
:: 构建,项目文件在当前目录
cmake --build .
pause

运行脚本

Run_App.bat
 @ECHO OFF
:: 加载ONEAPI环境,使得引用库在运行环境可见;将加载过程的输出重定向隐藏
Call "C:\Program Files (x86)\Intel\oneAPI\setvars.bat" intel64 vs2022 >NUL 2>&1
cd ./build/bin/
OpenMPDemo.exe

注意事项

  • 支持2023.2版本IntelLLVM编译器的CMake最低版本为3.25
  • 在project()中,指定CXX语言,就不用配置C语言选项(CMake默认启用C和C++)
  • CMAKE_CXX_COMPILER 、CMAKE_GENERATOR_TOOLSET 等变量建议通过 toolchain 文件设置
  • CMake使用的默认生成器为 Visual Studio 17 2022,因尚未探明之原因,其总将编译器设置为MSVC,故若要使用Intel编译器,推荐使用Ninja生成器
  • 在Intel编译器中,支持CMake的是icx
  • 编译时,需要设置OneAPI环境以使引用的标准库可见
  • 使用find_package(OpenMP REQUIRED)即可启用OpenMP支持,无需另行设置编译标记

标签:std,cmake,CMake,CXX,API,OpenMP,Heroius,Intel
From: https://www.cnblogs.com/heroius/p/17806091.html

相关文章

  • javaapi、spark、flink 创建Iceberg表,hive 和impala无法正常读取解决
    spark、flink创建Iceberg表中,元数据存储在hive的meta_store,发现hive或者impala无法正常读取报错。事实上解决方案是在spark、flink的SQL中执行语句:addiceberg相关引擎的runntime的jar;ALTERTABLEtSETTBLPROPERTIES('storage_handler'='org.apache.iceberg.mr.hive......
  • API管理平台搭建过程问题总结​
    API管理的定义和好处API管理是指对应用程序编程接口(API)进行集中管理、监控和维护的过程。API是用于不同软件之间进行通信和交互的编程接口,通过API管理可以有效地管理和控制API的使用、访问和安全性。API管理的好处包括:1、提高开发效率:通过API管理,开发团队可以更好地共享和重用API,避......
  • api-ms-win-core-path-l1-1-0.dll下载(win7-32位)
      下载 api-ms-win-core-path-l1-1-0.dll 后拷贝到文件夹:32位系统 c:\windows\system32  下载链接: https://www.dll-files.com/api-ms-win-core-path-l1-1-0.dll.html ......
  • 拼多多详情 API 接口数据采集及营销策略渠道店铺业务增长
    拼多多详情API接口可以提供丰富的商品信息和销售数据,通过数据采集和分析,企业可以制定更加精准的营销策略,促进业务增长。以下是使用拼多多详情API接口进行数据采集和营销策略制定的步骤和方法:步骤1:获取拼多多详情API接口的访问权限在拼多多开放平台注册并创建应用,获取API密......
  • 22 RSTP(Rapid STP/快速生成树)
    随着局域网规模的不断增长,STP拓扑收敛速度慢的问题逐渐凸显,因此,IEEE在2001年发布了802.1W标准,定义了RSTP(RapidSpanningTreeProtocol,快速生成树协议),RSTP在STP的基础上进行了改进,可实现网络拓扑的快速收敛。STP不足之处STP对计时器的依赖初始化场景STP采用计时器防止临时......
  • 如何调用API获取你想要的数据
    在现代软件开发中,API(应用程序编程接口)已经成为了连接不同系统和服务的桥梁。通过调用API,我们可以从各种数据源中获取所需的数据,并将其集成到我们的应用程序中。本文将介绍如何调用API获取你想要的数据,并提供详细的代码示例。一、了解API的基本概念在开始调用API之前,我们需要了解一......
  • vue3 compositon api 和 common下写业务逻辑的区别
    区别:Vue3的CompositionAPI是一种处理和组织Vue组件内部逻辑的方式。它可以让你更灵活地组织和复用你的代码。使用compositionAPI可以将组件的逻辑拆分为小的、独立的函数或模块,并使用setup函数进行组合和重用。这对于一些复杂的业务逻辑或需要高内聚、低耦合的逻辑非......
  • 如何建设企业级API网关​
    企业级API网关是现代软件架构中不可或缺的重要组成部分,它能够为整个系统提供安全可靠的入口,同时也是系统中不同业务模块之间交互的桥梁。API网关使得搭建一个新的应用服务变得简单、快捷、高效,同时,开发人员可以将更多的精力放在和业务紧密相关的工作中。企业级API网关主要作用包括......
  • 1api触发gitlab流水线
    是的,通过GitLabAPI,您可以修改文件内容,并在更改后自动触发CI/CD流水线。以下是步骤和示例:1.**修改文件内容**:   使用`RepositoryFilesAPI`更新文件内容。这将为您提供一个提交新文件内容的方式。 示例请求: ```http PUT/projects/:id/repository/fil......
  • Python 潮流周刊#15:如何分析 FastAPI 异步请求的性能?
    你好,我是猫哥。这里每周分享优质的Python、AI及通用技术内容,大部分为英文。标题取自其中一则分享,不代表全部内容都是该主题,特此声明。本周刊精心筛选国内外的250+信息源,为你挑选最值得分享的文章、教程、开源项目、软件工具、播客和视频、热门话题等内容。愿景:帮助所有读者精进......