llm.c的Makefile

源码

CC ?= clang
CFLAGS = -Ofast -Wno-unused-result -Wno-ignored-pragmas -Wno-unknown-attributes
LDFLAGS =
LDLIBS = -lm
INCLUDES =
CFLAGS_COND = -march=native

# Find nvcc
SHELL_UNAME = $(shell uname)
REMOVE_FILES = rm -f
OUTPUT_FILE = -o $@
CUDA_OUTPUT_FILE = -o $@

# NVCC flags
# -t=0 is short for --threads, 0 = number of CPUs on the machine
NVCC_FLAGS = -O3 -t=0 --use_fast_math
NVCC_LDFLAGS = -lcublas -lcublasLt
NVCC_INCLUDES =
NVCC_LDLIBS =
NCLL_INCUDES =
NVCC_CUDNN =
# overridable flag for multi-GPU training. by default we won't build with cudnn
# because it bloats up the compile time from a few seconds to ~minute
USE_CUDNN ?= 0

# autodect a lot of various supports on current platform
$(info ---------------------------------------------)

ifneq ($(OS), Windows_NT)
  NVCC := $(shell which nvcc 2>/dev/null)

  # Function to test if the compiler accepts a given flag.
  define check_and_add_flag
    $(eval FLAG_SUPPORTED := $(shell printf "int main() { return 0; }\n" | $(CC) $(1) -x c - -o /dev/null 2>/dev/null && echo 'yes'))
    ifeq ($(FLAG_SUPPORTED),yes)
        CFLAGS += $(1)
    endif
  endef

  # Check each flag and add it if supported
  $(foreach flag,$(CFLAGS_COND),$(eval $(call check_and_add_flag,$(flag))))
else
  CFLAGS :=
  REMOVE_FILES = del *.exe,*.obj,*.lib,*.exp,*.pdb && del
  SHELL_UNAME := Windows
  ifneq ($(shell where nvcc 2> nul),"")
    NVCC := nvcc
  else
    NVCC :=
  endif
  CC := cl
  CFLAGS = /Idev /Zi /nologo /Wall /WX- /diagnostics:column /sdl /O2 /Oi /Ot /GL /D _DEBUG /D _CONSOLE /D _UNICODE /D UNICODE /Gm- /EHsc /MD /GS /Gy /fp:fast /Zc:wchar_t /Zc:forScope /Zc:inline /permissive- \
   /external:W3 /Gd /TP /wd4996 /Fd$@.pdb /FC /openmp:llvm
  LDFLAGS :=
  LDLIBS :=
  INCLUDES :=
  NVCC_FLAGS += -I"dev"
  ifeq ($(WIN_CI_BUILD),1)
    $(info Windows CI build)
    OUTPUT_FILE = /link /OUT:$@
    CUDA_OUTPUT_FILE = -o $@
  else
    $(info Windows local build)
    OUTPUT_FILE = /link /OUT:$@ && copy /Y $@ $@.exe
    CUDA_OUTPUT_FILE = -o $@ && copy /Y $@.exe $@
  endif
endif

# Check and include cudnn if available
# Currently hard-coding a bunch of stuff here for Linux, todo make this better/nicer
# You need cuDNN from: https://developer.nvidia.com/cudnn
# Follow the apt-get instructions
# And the cuDNN front-end from: https://github.com/NVIDIA/cudnn-frontend/tree/main
# For this there is no installation, just download the repo to your home directory
# and then we include it below (see currently hard-coded path assumed in home directory)
ifeq ($(USE_CUDNN), 1)
  ifeq ($(SHELL_UNAME), Linux)
    # hard-coded path for now
    CUDNN_FRONTEND_PATH := $(HOME)/cudnn-frontend/include
    ifeq ($(shell [ -d $(CUDNN_FRONTEND_PATH) ] && echo "exists"), exists)
      $(info ✓ cuDNN found, will run with flash-attention)
      NVCC_INCLUDES += -I$(CUDNN_FRONTEND_PATH)
      NVCC_LDFLAGS += -lcudnn
      NVCC_FLAGS += -DENABLE_CUDNN
      NVCC_CUDNN = cudnn_att.o
    else
      $(error ✗ cuDNN not found. See the Makefile for our currently hard-coded paths / install instructions)
    endif
  else
    $(info → cuDNN is not supported right now outside of Linux)
  endif
else
  $(info → cuDNN is manually disabled by default, run make with `USE_CUDNN=1` to try to enable)
endif

# Check if OpenMP is available
# This is done by attempting to compile an empty file with OpenMP flags
# OpenMP makes the code a lot faster so I advise installing it
# e.g. on MacOS: brew install libomp
# e.g. on Ubuntu: sudo apt-get install libomp-dev
# later, run the program by prepending the number of threads, e.g.: OMP_NUM_THREADS=8 ./gpt2
# First, check if NO_OMP is set to 1, if not, proceed with the OpenMP checks
ifeq ($(NO_OMP), 1)
  $(info OpenMP is manually disabled)
else
  ifneq ($(OS), Windows_NT)
  # Detect if running on macOS or Linux
    ifeq ($(SHELL_UNAME), Darwin)
      # Check for Homebrew's libomp installation in different common directories
      ifeq ($(shell [ -d /opt/homebrew/opt/libomp/lib ] && echo "exists"), exists)
        # macOS with Homebrew on ARM (Apple Silicon)
        CFLAGS += -Xclang -fopenmp -DOMP
        LDFLAGS += -L/opt/homebrew/opt/libomp/lib
        LDLIBS += -lomp
        INCLUDES += -I/opt/homebrew/opt/libomp/include
        $(info ✓ OpenMP found)
      else ifeq ($(shell [ -d /usr/local/opt/libomp/lib ] && echo "exists"), exists)
        # macOS with Homebrew on Intel
        CFLAGS += -Xclang -fopenmp -DOMP
        LDFLAGS += -L/usr/local/opt/libomp/lib
        LDLIBS += -lomp
        INCLUDES += -I/usr/local/opt/libomp/include
        $(info ✓ OpenMP found)
      else
        $(info ✗ OpenMP not found)
      endif
    else
      # Check for OpenMP support in GCC or Clang on Linux
      ifeq ($(shell echo | $(CC) -fopenmp -x c -E - > /dev/null 2>&1; echo $$?), 0)
        CFLAGS += -fopenmp -DOMP
        LDLIBS += -lgomp
        $(info ✓ OpenMP found)
      else
        $(info ✗ OpenMP not found)
      endif
    endif
  endif
endif

# Check if OpenMPI and NCCL are available, include them if so, for multi-GPU training
ifeq ($(NO_MULTI_GPU), 1)
  $(info → Multi-GPU (OpenMPI + NCCL) is manually disabled)
else
  ifneq ($(OS), Windows_NT)
    # Detect if running on macOS or Linux
    ifeq ($(SHELL_UNAME), Darwin)
      $(info ✗ Multi-GPU on CUDA on Darwin is not supported, skipping OpenMPI + NCCL support)
    else ifeq ($(shell [ -d /usr/lib/x86_64-linux-gnu/openmpi/lib/ ] && [ -d /usr/lib/x86_64-linux-gnu/openmpi/include/ ] && echo "exists"), exists)
      $(info ✓ OpenMPI found, OK to train with multiple GPUs)
      NVCC_INCLUDES += -I/usr/lib/x86_64-linux-gnu/openmpi/include
      NVCC_LDFLAGS += -L/usr/lib/x86_64-linux-gnu/openmpi/lib/
      NVCC_LDLIBS += -lmpi -lnccl
      NVCC_FLAGS += -DMULTI_GPU
    else
      $(info ✗ OpenMPI is not found, disabling multi-GPU support)
      $(info ---> On Linux you can try install OpenMPI with `sudo apt install openmpi-bin openmpi-doc libopenmpi-dev`)
    endif
  endif
endif

# Precision settings, default to bf16 but ability to override
PRECISION ?= BF16
VALID_PRECISIONS := FP32 FP16 BF16
ifeq ($(filter $(PRECISION),$(VALID_PRECISIONS)),)
  $(error Invalid precision $(PRECISION), valid precisions are $(VALID_PRECISIONS))
endif
ifeq ($(PRECISION), FP32)
  PFLAGS = -DENABLE_FP32
else ifeq ($(PRECISION), FP16)
  PFLAGS = -DENABLE_FP16
else
  PFLAGS = -DENABLE_BF16
endif

# PHONY means these targets will always be executed
.PHONY: all train_gpt2 test_gpt2 train_gpt2cu test_gpt2cu train_gpt2fp32cu test_gpt2fp32cu profile_gpt2cu

# Add targets
TARGETS = train_gpt2 test_gpt2

# Conditional inclusion of CUDA targets
ifeq ($(NVCC),)
    $(info ✗ nvcc not found, skipping GPU/CUDA builds)
else
    $(info ✓ nvcc found, including GPU/CUDA support)
    TARGETS += train_gpt2cu test_gpt2cu train_gpt2fp32cu test_gpt2fp32cu
endif

$(info ---------------------------------------------)

all: $(TARGETS)

train_gpt2: train_gpt2.c
	$(CC) $(CFLAGS) $(INCLUDES) $(LDFLAGS) $< $(LDLIBS) $(OUTPUT_FILE)

test_gpt2: test_gpt2.c
	$(CC) $(CFLAGS) $(INCLUDES) $(LDFLAGS) $< $(LDLIBS) $(OUTPUT_FILE)

cudnn_att.o: cudnn_att.cu
	$(NVCC) -c $(NVCC_FLAGS) $(PFLAGS) $< $(NVCC_LDFLAGS) $(NVCC_INCLUDES) $(NVCC_LDLIBS)

train_gpt2cu: train_gpt2.cu $(NVCC_CUDNN)
	$(NVCC) $(NVCC_FLAGS) $(PFLAGS) $< $(NVCC_LDFLAGS) $(NVCC_INCLUDES) $(NVCC_LDLIBS) $(CUDA_OUTPUT_FILE) $(NVCC_CUDNN)

train_gpt2fp32cu: train_gpt2_fp32.cu
	$(NVCC) $(NVCC_FLAGS) $< $(NVCC_LDFLAGS) $(NVCC_INCLUDES) $(NVCC_LDLIBS) $(CUDA_OUTPUT_FILE)

test_gpt2cu: test_gpt2.cu $(NVCC_CUDNN)
	$(NVCC) $(NVCC_FLAGS) $(PFLAGS) $< $(NVCC_LDFLAGS) $(NVCC_INCLUDES) $(NVCC_LDLIBS) $(CUDA_OUTPUT_FILE) $(NVCC_CUDNN)

test_gpt2fp32cu: test_gpt2_fp32.cu
	$(NVCC) $(NVCC_FLAGS) $< $(NVCC_LDFLAGS) $(NVCC_INCLUDES) $(NVCC_LDLIBS) $(CUDA_OUTPUT_FILE)

profile_gpt2cu: profile_gpt2.cu $(NVCC_CUDNN)
	$(NVCC) $(NVCC_FLAGS) $(PFLAGS) -lineinfo $< $(NVCC_LDFLAGS) $(NVCC_INCLUDES) $(NVCC_LDLIBS)  $(CUDA_OUTPUT_FILE) $(NVCC_CUDNN)

clean:
	$(REMOVE_FILES) $(TARGETS)

解读

这是一个使用 CUDA 和一些可选的其他库(如 cuDNN、OpenMPI、NCCL)的项目的 Makefile,它用于编译和链接 C 和 CUDA 程序。以下是主要部分的中文解读:
- 定义了一些变量,用于存储编译器选项(如 CFLAGS)、库(`LDLIBS`)、包含文件路径(`INCLUDES`),以及一些条件编译标志(`CFLAGS_COND`)。
- 检测系统类型,配置对应的命令和变量,比如在 Windows 系统上使用 cl 编译器和删除文件的命令。
- 通过命令查找 nvcc 编译器的路径,这是 NVIDIA 的 CUDA 编译器。
- 检查并且添加支持的编译器标志。
- 如果设置了 USE_CUDNN 变量,并且在 Linux 系统上找到了 cuDNN 库和头文件路径,那么就将 cuDNN 加入编译选项中。
- 检查 OpenMP 支持,如果支持,那么添加 OpenMP 相关的编译选项。
- 检查是否存在 OpenMPI 和 NCCL 支持,这两者用于多 GPU 训练。
- 设置精度选项,可以是 FP32(单精度)、`FP16`(半精度)或 BF16(谷歌的半精度格式)。
- 定义了一系列的伪目标(`.PHONY`),用于编译和测试不同配置下的项目。
- 根据环境配置和 nvcc 的存在与否,确定要构建的目标(`TARGETS`)。
- 最后,定义了各种编译目标的规则,用于编译和链接程序,以及一个 clean 目标用于清除生成的文件。
整个 Makefile 通过多个检测和条件判断,智能地配置了编译环境,并提供了灵活的编译选项,以便利用 CUDA 加速 GPU 编程。 

为了将上面提供的NVIDIA CUDA GPU Makefile修改为适用于AMD GPU平台的Makefile,我们需要使用AMD的ROCm工具链而不是NVIDIA的 CUDA 和 cuDNN 库。下面是如何进行一些基本转换的一个示例:

# ROCm configuration
ROCm_PATH ?= /opt/rocm
HIPCC := $(ROCm_PATH)/bin/hipcc

# Common flags
CFLAGS = -O3 -Wall -Wextra
LDFLAGS =
LDLIBS = -lm

# AMD GPU specific flags
HIPCC_FLAGS = -O3 --amdgpu-target=gfx803 # You might want to specify your own GPU architecture here
HIPCC_LDFLAGS =
HIPCC_INCLUDES =
HIPCC_LDLIBS =

# PHONY targets - these recipes will always be run
.PHONY: all clean

# Add targets
TARGETS = train_gpt2 test_gpt2

all: $(TARGETS)

train_gpt2: train_gpt2.cpp
    $(HIPCC) $(CFLAGS) $(HIPCC_INCLUDES) $(LDFLAGS) $< $(LDLIBS) -o $@

test_gpt2: test_gpt2.cpp
    $(HIPCC) $(CFLAGS) $(HIPCC_INCLUDES) $(LDFLAGS) $< $(LDLIBS) -o $@

clean:
    rm -f $(TARGETS)

这个示例 Makefile 使用了 hipcc 编译器,它是ROCm工具链的一部分,用以支持AMD GPU上的GPU计算。请注意以下几点:
1. $(ROCm_PATH) 为ROCm安装路径,默认通常为 /opt/rocm,但你需要根据管路上具体的安装位置进行相应调整。
2. $(HIPCC) 被设置成ROCm工具链中的 hipcc 编译器的路径。
3. 我们为 HIPCC_FLAGS 添加了一个 -O3 优化标志和一个 --amdgpu-target 参数,该参数后跟的是你期望代码运行的具体AMD GPU架构,如 gfx803。基于你使用的GPU,你可能需要更改这个参数。
4. 所有原有的CUDA相关变量和规则(例如 NVCC_FLAGS、`NVCC_LDLIBS`、`cudnn_att.o`、`train_gpt2cu` 等)都被移除或替换为适合AMD平台的变量和规则。
5. 目标名称(train_gpt2、test_gpt2等)和源文件名现在反映了其作为C++源的性质。
6. 由于AMD GPU不支持cuDNN,所以我们移除了所有与cuDNN相关的配置项。
对于其他使用了 (CUDA_)OUTPUT_FILE 和 REMOVE_FILES 变量的规则,需要根据上下文具体情况进行必要的调整。
这个Makefile还十分简化,以说明AMD GPU 平台的CPU/GPU编译过程。在实际情况中,你可能需要进一步适应其他库的链接(例如 ROCm 的 rocBLAS、`MIOpen` 等等),并进行跟你的应用相关的其他调整。请参照ROCm官方文档获取更多信息。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

5.神经网络-激活函数

目录 1. 激活函数不是阶跃函数 1.1 激活函数和阶跃函数都是非线性函数 1.2 激活函数不是阶跃函数 2. sigmoid 函数 2.1 sigmoid 函数表达式 2.2 sigmoid 函数 Python 实现 2.4 sigmoid 函数图 3. ReLU 函数 3.1 ReLU 函数表达式 3.2 ReLU 函数 Python 实现 3.4 ReLU…

Chatgpt的应用场景

文案创作类&#xff1a; 作为一名大型语言模型&#xff0c;ChatGPT可以为使用者提供多种文本处理和文字创作方面的服务&#xff0c;例如&#xff1a; 文本生成和创作 ChatGPT可以基于您提供的主题、关键词或文本段落&#xff0c;生成符合使用者要求的新文本。这些文本可以是文…

Golang | Leetcode Golang题解之第83题删除排序链表中的重复元素

题目&#xff1a; 题解&#xff1a; func deleteDuplicates(head *ListNode) *ListNode {if head nil {return nil}cur : headfor cur.Next ! nil {if cur.Val cur.Next.Val {cur.Next cur.Next.Next} else {cur cur.Next}}return head }

C++的数据结构(二)

一、链表的基本概念 链表&#xff08;Linked List&#xff09;是一种物理存储单元上非连续的、非顺序的线性数据结构&#xff0c;数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列节点&#xff08;链表中每一个元素称为节点&#xff09;组成&#xff0c;节点…

(二刷)代码随想录第4天|24. 两两交换链表中的节点 ● 19.删除链表的倒数第N个节点

24. 两两交换链表中的节点 24. 两两交换链表中的节点 - 力扣&#xff08;LeetCode&#xff09; 代码随想录 (programmercarl.com) 帮你把链表细节学清楚&#xff01; | LeetCode&#xff1a;24. 两两交换链表中的节点_哔哩哔哩_bilibili 给你一个链表&#xff0c;两两交换其…

【计算机网络】物理层传输介质 习题3

双绞线是用两根绝缘导线绞合而成的&#xff0c;绞合的目的是( )。 A.减少干扰 B.提高传输速度 C.增大传输距离 D.增大抗拉强度 在电缆中采用屏蔽技术带来的好处主要是( ) A.减少信号衰减 B. 减少电磁干扰辐射 C.减少物理损坏 D. 减少电缆的阻抗 利用一根同轴电缆互连主机构成…

docker安装时报错:Error: Nothing to do

安装docker时报以下错误 解决方法&#xff1a; 1.下载关于docker的相关依赖环境 yum -y install yum-utils device-mapper-persistent-data lvm22.设置下载Docker的镜像源 yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo3…

Java 常见集合类

集合的整体框架 Java 的集合&#xff0c;也可以叫做容器&#xff0c;根据集合的整体框架可以看出&#xff0c;主要是两大集合接口&#xff1a;第一个是 Collection 接口&#xff0c;主要用来存放单一的元素对象&#xff1b;另一个是 Map 接口&#xff0c;主要用于存储键值对。…

Linux·基本指令

从本节开始将新开一个关于Linux操作系统的板块&#xff0c;其实Linux也没什么太神秘的&#xff0c;就是一个操作系统(OS)嘛&#xff0c;跟Windows操作系统是一个概念&#xff0c;只不过Windows中的大部分操作都是用光标点击来进行人机交互&#xff0c;但是Linux是通过输入命令行…

SQLite性能测试(插入)

最近一直在思考一个问题&#xff0c;SQLite 做到这么轻量级&#xff0c;那它注定不会像 MySql 一样强性能&#xff0c;那么它的性能怎么样呢&#xff1f;并发量多高呢&#xff1f; 官方解释&#xff1a; About SQLite 最大数据库大小&#xff1a;281TB 最大行大小&#xff1…

俄罗斯方块的代码实现

文章目录 首先是头文件的引入部分接下来是一些预处理指令接下来定义了两个结构体&#xff1a;接下来是全局变量g_hConsoleOutput&#xff0c;用于存储控制台输出句柄。之后是一系列函数的声明最后是main函数源码 首先是头文件的引入部分 包括stdio.h、string.h、stdlib.h、tim…

Neo4j 之安装和 CQL 基本命令学习

正常使用结构化的查询语言 SQL&#xff08;Structured Query Language&#xff09;较多一些&#xff0c;但是像 Neo4j 这种非结构化的图形数据库来说&#xff0c;就不得不学习下 CQL&#xff08;Cypher Query Language&#xff09;语言了。如果你之前学过 《离散数学》或《图论…

【北京迅为】《iTOP-3588从零搭建ubuntu环境手册》-第6章 安装Samba

RK3588是一款低功耗、高性能的处理器&#xff0c;适用于基于arm的PC和Edge计算设备、个人移动互联网设备等数字多媒体应用&#xff0c;RK3588支持8K视频编解码&#xff0c;内置GPU可以完全兼容OpenGLES 1.1、2.0和3.2。RK3588引入了新一代完全基于硬件的最大4800万像素ISP&…

Debian安装Redis、RabbitMQ、Nacos

安装Redis&#xff1a; 启动Redis、开机自启动 sudo systemctl start redis-server #启动sudo systemctl enable redis-server #开机自启 Redis状态(是否在运行) sudo systemctl status redis-server #查看运行状态 redis-cli ping # 客户端尝试连接 安装RabbitMQ&#xff0c;…

Rust学习笔记(中)

前言 笔记的内容主要参考与《Rust 程序设计语言》&#xff0c;一些也参考了《通过例子学 Rust》和《Rust语言圣经》。 Rust学习笔记分为上中下&#xff0c;其它两个地址在Rust学习笔记&#xff08;上&#xff09;和Rust学习笔记&#xff08;下&#xff09;。 错误处理 pani…

百问C语言第1问——彻底弄懂define用法

系列文章目录 玩转指针专栏 趣味c程序专栏 一.c语言关系操作符练习题(新手必会) 一.c语言常见概念(超全) 一.趣味c程序—关机程序&#xff08;整蛊同学版) 二.趣味c程序—猜数字游戏&#xff08;含干货知识点 三.趣味c程序—打印图形&#xff08;1&#xff09;&#xff08;含干…

前端笔记-day05

文章目录 01-结构伪类选择器02-结构伪类选择器-公式用法03-伪元素选择器04-盒子模型-组成05-盒子模型-边框线06-盒子模型-单方向边框线07-盒子模型-内边距08-盒子模型-padding多值写法09-盒子模型-尺寸计算10-盒子模型-版心居中11-清除默认样式12-元素溢出overflow13-外边距合并…

Java | Leetcode Java题解之第83题删除排序链表中的重复元素

题目&#xff1a; 题解&#xff1a; class Solution {public ListNode deleteDuplicates(ListNode head) {if (head null) {return head;}ListNode cur head;while (cur.next ! null) {if (cur.val cur.next.val) {cur.next cur.next.next;} else {cur cur.next;}}return…

E - Yet Another Sigma Problem(ABC字典树)

思路&#xff1a;我们可以发现两个字符串的最长公共前缀就是字典树中的最近公共祖先。然而这道题&#xff0c;比如说某个结点是x个字符串的前缀&#xff0c;那么当前结点对答案的贡献为x * (x - 1) / 2&#xff0c;就是x中任选两个字符串组合&#xff0c;因为在这之前&#xff…

Linux提权--本地环境变量文件配合 SUID

免责声明:本文仅做技术交流与学习... 目录 背景: 前提条件: 演示: 实战中如何操作? 探针发现: 背景: 环境变量提权--------> 背景&#xff1a; 管理员编译了程序&#xff0c;给予了程序管理员运行的方案, 攻击通过对程序的运行调试反编译等得到了程序的运行大概逻辑, …