llm.c的Makefile

news2024/11/17 15:39:36

源码

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官方文档获取更多信息。

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

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

相关文章

洁净环境微生物监测的解决方案

药品污染控制 Manufacturing 无菌药品生产污染控制意义 01 CCS策略 无菌药品生产污染控制策略&#xff08;CCS) &#xff1a;来自于现行产品和工艺理解&#xff0c;为确保工艺性能和产品质量&#xff0c;所计划的一套体系&#xff0c;针对微生物、热原/内毒素和微粒的控制方…

文本提取新技能:学会按行数批量提取,轻松应对各种需求

在数字化时代&#xff0c;文本处理成为我们日常生活和工作中不可或缺的一部分。无论是从网页、文档还是数据库中提取信息&#xff0c;文本提取技能都显得尤为重要。而按行数批量提取文本内容&#xff0c;更是文本处理中的一项高效且实用的技能。本文将介绍办公提效工具如何按行…

工业机器人应用实践之玻璃涂胶(篇一)

工业机器人 工业机器人&#xff0c;即面向工业领域的机器人。工业机器人是广泛用于工业领域的多关节机械手或多自由度的机器装置&#xff0c;具有一定的自动性&#xff0c;可依靠自身的动力能源和控制能力实现各种工业加工制造功能。工业机器人被广泛应用于电子、物流、化工等…

Verlog-流水灯-FPGA

Verlog-流水灯-FPGA 引言&#xff1a; ​ 随着电子技术的飞速发展&#xff0c;现场可编程门阵列&#xff08;FPGA&#xff09;已成为电子设计自动化&#xff08;EDA&#xff09;领域中不可或缺的组件。FPGA以其高度的灵活性和可定制性&#xff0c;广泛应用于通信、图像处理、工…

【系统分析师】软件架构设计

文章目录 1、构件与软件复用1.1 主流构件标准1.2 构件获取与管理1.3 构件复用的方法 2、软件架构概述3、软件架构建模4、软件架构风格4.1 经典架构风格4.2 层次架构风格4.3 富互联网应用-RIA 5、面向服务的架构5.1 SOA概述5.2 SOA的关键技术5.3 SOA的实现方法 6、软件架构评估6…

ARM时钟树结构(GD32)

时钟树的简易框图 初始化配置系统时钟 配置系统初始化时钟&#xff08;参考手册&#xff09; 对应hal库函数 使用72MHz的系统时钟 do -----------while&#xff08;0&#xff09;的使用方法 系统时钟 #include <stdint.h> #include "gd32f30x.h"int main(void)…

实现MYSQL8.3.0 版本流量抓取

实现MYSQL8.3.0 版本流量抓取 根据测试需求&#xff0c;需要抓取MYSQL8.3.0流量包&#xff0c;使用wireshark 数据库客户端实现 安装数据库服务端 这里就不给详细操作方法&#xff0c; 网上教程一大堆&#xff0c;小编这里是最新的MYSQL 8.3.0版本 安装成功后&#xff0c;创…

PyQt6--Python桌面开发(7.QTextEdit多行富文本框控件)

QTextEdit多行富文本框控件 保存文件到本地QLine多行文本框.ui import sys import time from PyQt6.QtGui import QValidator,QIntValidator from PyQt6.QtWidgets import QApplication,QLabel,QLineEdit,QTextEdit from PyQt6 import uic,QtGuiif __name__ __main__:appQApp…

管道液位传感器可以应用在哪些领域

管道液位传感器是一种利用光学原理来检测水管液位的传感器&#xff0c;其工作原理基于光线在水和空气中折射率不同的特性。通过光电管道传感器&#xff0c;可以有效解决传统机械式传感器存在的低精度、卡死失效等问题&#xff0c;同时也避免了电容式传感器因感度衰减而导致的不…

差分信号的前世今生

网上搜索到一篇简洁文章&#xff0c;描述差分信号&#xff0c;我觉得挺好&#xff0c;和大家一起分享&#xff0c;同时也发表个人的浅浅想法。 一、原文摘录 所谓差分方式传输&#xff0c;就是发送端在两条信号线上传输的幅值是相等的&#xff0c;相位是相反的电信号&#xff…

30年赚1000亿美元--“量化之王”和他最传奇的基金“大奖章”的秘密

文艺复兴是华尔街最成功、最神秘的机构之一。从1988-2018年的30年里&#xff0c;文艺复兴仅向内部员工开放的旗舰基金“大奖章”累计创造了超过1000亿美元的收益&#xff0c;年均回报率高达39%。作为对比&#xff0c;同期“股神”巴菲特的年均回报率为20.5%。 而且&#xff0c;…

怎么将一张包含多个帧的精灵图分割成一帧一帧的小图

工具 图片分割 - 图文工具箱 - imgtool.net 设置行列 下载即可

【6大模型让你的沟通汇报更有条理】项目管理常见问题大揭秘 03

6大模型让你的沟通汇报更有条理 虽然头脑中构思众多&#xff0c;一开口却发现空白一片&#xff1f; 工作表现出色&#xff0c;汇报时却总是支支吾吾不知从何说起&#xff1f; 生性腼腆&#xff0c;却难以避免需要站在众人面前发言&#xff1f; 阿道掐指一算&#xff1a;你需…

短剧APP开发,为短剧市场提供更多活力

近年来&#xff0c;短剧一直是一个大热赛道&#xff0c;不仅各大视频平台刮起了一股短剧热潮&#xff0c;各大品牌也纷纷开始进军短剧市场。短剧作为当下的流量密码&#xff0c;深受各大短剧观众与创业者的关注。吸引了大量的资本、制作方涌入到市场中&#xff0c;短剧行业发展…

[GESP样题 四级] 填幻方和幸运数

B3940 [GESP样题 四级] 填幻方 题目 在一个NN 的正方形网格中&#xff0c;每个格子分别填上从 1 到 NN 的正整数&#xff0c;使得正方形中任一行、任一列及对角线的几个数之和都相等&#xff0c;则这种正方形图案就称为“幻方”&#xff08;输出样例中展示了一个33 的幻方&am…

postgresql中写python去读取HDFS数据,像表一样使用。

简介 首先postgresql是支持python的&#xff0c;在安装postgresql数据库的时候需要执行python支持。可以使用python进行写fundcation 自然也就可以自定义funcation去读取HDFS文件&#xff0c;以此替换掉hive的&#xff0c;省去中间频繁切换服务器的麻烦。 安装postgresql use…

民航电子数据库:select查询时部分字段缺失

目录 前言异常排查原因解决使用systemPath标签引入本地Jar包后无法打包 前言 1、对接民航电子数据库 2、框架为shardingsphere caedb mybatis 3、部分SQL查询时&#xff0c;会出现字段缺失的情况 4、查看日志打印出来的SQL&#xff0c;字段并未缺失 异常 这里省略SQL语句…

【Java】/*逻辑控制语句和输入输出—快速总结*/

目录 前言 一、分支语句 1.1 if 语句 1.2 switch 语句 二、循环语句 2.1 while 循环 2.1.1 break 2.1.2 continue 2.2 for 循环 2.3 do_while 循环 三、逻辑语句的小结 四、Java 中的输入输出 4.1 输出到控制台 4.2 从键盘输入 前言 Java 中的逻辑控制语句和C语…

1分钟搞定Pandas DataFrame创建与索引

1.DataFrame介绍 DataFrame 是一个【表格型】的数据结构,可以看作是【由Series组成的字典】(共用同一个索引)。DataFrame 由按一定顺序排列的多列数据组成。设计初衷是将 Series 的使用场景从一维扩展到多维。DataFrame 既有行索引,也有列索引。 行索引:index 列索引:co…

【18-Ⅱ】Head First Java 学习笔记

HeadFirst Java 本人有C语言基础&#xff0c;通过阅读Java廖雪峰网站&#xff0c;简单速成了java&#xff0c;但对其中一些入门概念有所疏漏&#xff0c;阅读本书以弥补。 第一章 Java入门 第二章 面向对象 第三章 变量 第四章 方法操作实例变量 第五章 程序实战 第六章 Java…