精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

CuPy vs. NumPy,使用 GPU 速度提升 10 倍

開發(fā) 開發(fā)工具
CuPy 是由專注于深度學(xué)習(xí)技術(shù)的日本公司 Preferred Networks 開發(fā)的開源庫,旨在提供與 NumPy 兼容的接口,以便使用 CUDA 在 NVIDIA GPU 上執(zhí)行計(jì)算。

如果你使用 Numpy 頻率非常高,并且幸運(yùn)地?fù)碛幸慌_(tái)配備 Nvidia GPU 的系統(tǒng),那么你有一個(gè)相對(duì)簡(jiǎn)單的方法來提升你的計(jì)算運(yùn)行時(shí)間。怎么做?很簡(jiǎn)單,使用 CuPy Python 庫代替 Numpy。

什么是 Numpy?

我猜你已經(jīng)知道 Numpy Python 庫的全部含義了;否則,你可能不會(huì)讀這篇文章。NumPy 是用 C 語言編寫的,它支持快速數(shù)字運(yùn)算,尤其適用于多維數(shù)組和矩陣,并且它還提供了一系列數(shù)學(xué)函數(shù)來高效地操作這些數(shù)組。

什么是 CuPy,為什么需要它?

CuPy 是由專注于深度學(xué)習(xí)技術(shù)的日本公司 Preferred Networks 開發(fā)的開源庫,旨在提供與 NumPy 兼容的接口,以便使用 CUDA 在 NVIDIA GPU 上執(zhí)行計(jì)算。


CUDA(統(tǒng)一計(jì)算設(shè)備架構(gòu))是由 NVIDIA 創(chuàng)建的并行計(jì)算平臺(tái)和應(yīng)用程序編程接口 (API) 模型。它允許軟件開發(fā)人員和軟件工程師使用支持 CUDA 的圖形處理單元 (GPU) 進(jìn)行通用處理。

CuPy 旨在成為 Numpy 的直接替代品,讓你能夠以最少的代碼更改充分利用 GPU 的并行計(jì)算能力。CuPy 的 API 與 NumPy 高度兼容,這意味著在許多情況下,它可以直接替代 Numpy。

至于為什么需要 CuPy,答案很簡(jiǎn)單——速度。對(duì)于可并行化的操作,CuPy 可以利用 GPU 以比 CPU 更快的速度執(zhí)行計(jì)算,尤其是在大規(guī)模數(shù)值計(jì)算方面。這對(duì)于科學(xué)計(jì)算、數(shù)據(jù)分析、機(jī)器學(xué)習(xí)、深度學(xué)習(xí)和圖像處理任務(wù)尤其有利。

先決條件

  • Nvidia GPU

首先,你的系統(tǒng)上需要有一塊 Nvidia GPU。在系統(tǒng)提示符下輸入以下命令來檢查你的 GPU。

>>
(base) PS C:\Users\yunduojun> nvidia-smi
Fri Mar 22 11:41:34 2024
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 551.61                 Driver Version: 551.61         CUDA Version: 12.4     |
|-----------------------------------------+------------------------+----------------------+
| GPU  Name                     TCC/WDDM  | Bus-Id          Disp.A | Volatile Uncorr. ECC |
| Fan  Temp   Perf          Pwr:Usage/Cap |           Memory-Usage | GPU-Util  Compute M. |
|                                         |                        |               MIG M. |
|=========================================+========================+======================|
|   0  NVIDIA GeForce RTX 4070 Ti   WDDM  |   00000000:01:00.0  On |                  N/A |
| 32%   24C    P8              9W /  285W |     843MiB /  12282MiB |      1%      Default |
|                                         |                        |                  N/A |
+-----------------------------------------+------------------------+----------------------+

如果無法識(shí)別nvidia-smi命令(并且你使用的是Nvidia GPU) ,則可能需要安裝驅(qū)動(dòng)程序。相關(guān)說明請(qǐng)見頁面下方。

此外,你擁有的任何 GPU 都需要具有 3.0 或更高的計(jì)算能力。你可以使用以下命令查看 GPU 的計(jì)算能力:

$ nvidia-smi --query-gpu=compute_cap --format=csv 
# 在我的系統(tǒng)上輸出以下內(nèi)容
compute_cap 
8.9
  • 安裝 WSL Ubuntu Linux

由于我使用的是 Windows 系統(tǒng),而在該平臺(tái)上安裝 Cuda 比較復(fù)雜,因此我選擇在 Linux 下進(jìn)行安裝。幸運(yùn)的是,Windows 的 Linux 子系統(tǒng) (WSL) 可以方便地實(shí)現(xiàn)這一點(diǎn)。

要在 Windows 上安裝它,請(qǐng)打開 PowerShell 命令窗口,然后輸入:-

(base) PS C:\Users\thoma> wsl --install
Installing: Windows Subsystem for Linux
Windows Subsystem for Linux has been installed.
Installing: Ubuntu
Ubuntu has been installed.
The requested operation is successful. Changes will not be effective until the system is rebooted.

接下來,重啟你的電腦。WSL 應(yīng)該會(huì)自動(dòng)啟動(dòng),并要求你設(shè)置用戶名和密碼。如果一切順利,你的命令窗口應(yīng)該如下所示:

圖片圖片

要退出 WSL Linux,請(qǐng)?jiān)谔崾痉螺斎雃xit。在常規(guī) PowerShell 命令窗口中,輸入ubuntu即可返回 Linux Shell。

  • 為你的 GPU 和系統(tǒng)安裝最新的 Nvidia 驅(qū)動(dòng)程序

轉(zhuǎn)到 Nvidia 網(wǎng)站并安裝與你的系統(tǒng)和 GPU 規(guī)格相關(guān)的最新驅(qū)動(dòng)程序。www.nvidia.com

  • 在 WSL 上安裝 Miniconda

安裝 WSL 并啟動(dòng)它后,輸入以下命令來獲取 Miniconda 并安裝它。

$ wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
$ ./Miniconda3-latest-Linux-x86_64.sh
  • 安裝 CUDA 工具包

轉(zhuǎn)到CUDA Toolkit 下載頁面并選擇符合你的系統(tǒng)要求和操作系統(tǒng)的版本。

CuPy 的安裝

現(xiàn)在首先設(shè)置我們的 Python 開發(fā)環(huán)境。

#創(chuàng)建我們的測(cè)試環(huán)境
(base)$ conda create -n cupy_test pythnotallow= 3.11 -y
# 現(xiàn)在激活它
(base)$ conda activate cupy_test

安裝所需的庫。

(cupy_test) $ conda install -c conda - forge cupy jupyter numpy pandas matplotlib -y

現(xiàn)在在命令提示符中輸入jupyter notebook 。你應(yīng)該會(huì)看到瀏覽器中打開了一個(gè) Jupyter Notebook。如果沒有自動(dòng)打開,你可能會(huì)在jupyter notebook 命令后看到一整屏的信息。在屏幕底部附近,會(huì)有一個(gè) URL,你應(yīng)該將其復(fù)制并粘貼到瀏覽器中以啟動(dòng) Jupyter Notebook。

你的 URL 將與我的不同,但它應(yīng)該看起來像這樣:-

http://127.0.0.1:8888/tree?token=3b9f7bd07b6966b41b68e2350721b2d0b6f388d248cc69da


注意:在下面的時(shí)間安排中,我連續(xù)多次運(yùn)行了 Numpy 和 CuPy 進(jìn)程,并分別獲得了最佳時(shí)間。這確實(shí)在一定程度上有利于 CuPy 的運(yùn)行,因?yàn)槊看?CuPy 運(yùn)行的首次調(diào)用都會(huì)產(chǎn)生少量開銷,但總的來說,我認(rèn)為這是一個(gè)更公平的比較。

示例 1

一個(gè)簡(jiǎn)單的數(shù)組數(shù)學(xué)運(yùn)算。

在此示例中,我們?cè)O(shè)置了幾個(gè)大型一維數(shù)組,然后對(duì)每個(gè)數(shù)組元素執(zhí)行簡(jiǎn)單的加法運(yùn)算。請(qǐng)注意,用于 CuPy 處理的數(shù)組是使用 CuPy 而非 NumPy 設(shè)置的。這一點(diǎn)很重要,因?yàn)檫@意味著數(shù)組數(shù)據(jù)將存儲(chǔ)在 GPU 主內(nèi)存中,而不是 CPU 主內(nèi)存中。

import numpy as np 
import cupy as cp 

from timeit import default_timer as timer    

# func1 和 func3 將在 CPU 上運(yùn)行
def  func1 ( a ):                                  
    for i in  range ( len (a)): 
        a[i]+= 1       
       
# func2 和 func4 將在 GPU 上運(yùn)行              
def  func2 ( a ):
    for i in  range ( len (a)): 
        a[i]+= 2       
   
def  func3 ( a ):                                  
    a+= 3    
    
def  func4 ( a ):                                  
    a+= 4

if __name__=="__main__": 
    n1 = 300000000                          
    a1 = np.ones(n1, dtype = np.float64) 

    # had to make this array much smaller than
    # the others due to slow loop processing on the GPU
    n2 = 300000                      
    a2 = cp.ones(n2, dtype = cp.float64) 

    n3 = 300000000                           
    a3 = np.ones(n1, dtype = np.float64) 
    n4 = 300000000                      
    a4 = cp.ones(n2, dtype = cp.float64) 
   
    start = timer() 
    func1(a1) 
    print("without GPU/for loop:", timer()-start)     
      
    start = timer() 
    func2(a2) 
    # wait for all calcs to complete
    cp.cuda.Stream.null.synchronize()
    print("with GPU:/for loop", timer()-start) 

    start = timer() 
    func3(a3) 
    print("without GPU:vectorization", timer()-start)     

    start = timer() 
    func4(a4) 
    # wait for all calcs to complete
    cp.cuda.Stream.null.synchronize()
    print("with GPU:vectorization", timer()-start) 
    print()

    print("a1 = ",a1)
    print("a2 = ",a2)
    print("a3 = ",a3)
    print("a4 = ",a4)

輸出如下:

without GPU/for loop: 25.486853414004145
with GPU:/for loop 4.358431388995086
without GPU:vectorization 0.13804959499998404
with GPU:vectorization 0.07079174599994076

a1 =  [2. 2. 2. ... 2. 2. 2.]
a2 =  [3. 3. 3. ... 3. 3. 3.]
a3 =  [4. 4. 4. ... 4. 4. 4.]
a4 =  [5. 5. 5. ... 5. 5. 5.]

需要注意的是,使用 GPU 數(shù)據(jù)的循環(huán)非常慢!盡管 CuPy for 循環(huán)測(cè)試的數(shù)組大小是 Numpy 數(shù)組大小的 1/1000,但執(zhí)行時(shí)間卻只有 Numpy 的 1/7。

for 循環(huán)將在 CPU 上運(yùn)行,并導(dǎo)致每次迭代時(shí)數(shù)據(jù)在 CPU 和 GPU 之間傳輸,從而加劇性能損失。

相比之下,看看我們?yōu)槭噶炕僮鞴?jié)省的時(shí)間。GPU 處理數(shù)據(jù)的速度是 CPU 的兩倍。

如果你嘗試處理不同的數(shù)據(jù)項(xiàng)數(shù)量,你會(huì)注意到,隨著數(shù)據(jù)項(xiàng)數(shù)量的減少,GPU 的優(yōu)勢(shì)會(huì)逐漸減弱。這是可以預(yù)料的,你需要對(duì)數(shù)據(jù)進(jìn)行一些測(cè)試,找到一個(gè)最佳平衡點(diǎn),以證明將處理轉(zhuǎn)移到 GPU 所需的額外努力是合理的。

在繼續(xù)下一個(gè)示例之前,CuPy 還為類似情況提供了另一種選擇——自定義 CUDA 內(nèi)核。這些內(nèi)核使用類似 C 語言的語法編寫,可以根據(jù)你的需求調(diào)用各種 CuPy 函數(shù)。我們將使用的內(nèi)核函數(shù)是ElementwiseKernel().

我們檢查一下代碼。

import numpy as np 
import cupy as cp 
from timeit import default_timer as timer 

# ElementwiseKernel 函數(shù)
add_five_kernel = cp.ElementwiseKernel( 
    'float64 x' , 
    'float64 y' , 
    'y = x + 5' , 
    'add_five'
 ) 

def  func5 ( a ):
    add_five_kernel(a, a)   # 就地修改

n5 = 300000000
 a5 = cp.ones(n5, dtype=cp.float64) 

start = timer() 
    
func5(a5) 
cp.cuda.Stream.null.synchronize() 
print("with GPU/ElementwiseKernel:" , timer()-start)

在這種情況下,輸出顯示內(nèi)核運(yùn)行時(shí)間介于矢量化 CPU 和矢量化 GPU 操作所需的時(shí)間之間。

使用GPU/ElementwiseKernel:0.011662766003923025
 a5 = [ 6.  6.  6. ... 6.  6.  6. ]

有關(guān)可用CuPy 核函數(shù)的完整列表,請(qǐng)查看你所使用版本的文檔。

示例2

稍微復(fù)雜一點(diǎn)的數(shù)組操作。

在此示例中,我們將使用 CuPy 和 Numpy 庫中內(nèi)置的matmul運(yùn)算進(jìn)行多維矩陣乘法。每個(gè)數(shù)組的大小為 10000 x 10000,包含 1 到 100 之間的隨機(jī)浮點(diǎn)數(shù)。

# 首先
import numpy as np 
from timeit import default_timer as timer 

# 設(shè)置種子以實(shí)現(xiàn)可重復(fù)性
np.random.seed( 0 ) 

# 生成兩個(gè) 10000x10000 的 1 到 100 之間的隨機(jī)浮點(diǎn)數(shù)數(shù)組
A = np.random.uniform(low= 1.0 , high= 100.0 , size=( 10000 , 10000 )) 
B = np.random.uniform(low= 1.0 , high= 100.0 , size=( 10000 , 10000 )) 

# 執(zhí)行矩陣乘法
start = timer() 
C = np.matmul(A, B) 


# 由于矩陣很大,將它們?nèi)看蛴〕鰜聿磺袑?shí)際。
# 相反,你可以打印結(jié)果的形狀和一小部分以進(jìn)行驗(yàn)證。

print("結(jié)果矩陣的一小部分:\n" , C[:5 , :5]) 
print("不使用 GPU:", timer()-start)

輸出如下

結(jié)果矩陣的一小部分:
[[25461282.56020853 25168348.08695598 25212522.35402665 25303307.69696668 25277886.16204746] 
[25114760.67252064 25197555.19361381 25340074.95867983 25341847.41707999 25373123.1113671 ] 
[25381820.17590097 25326519.29503381 25438611.20780989 25596935.44312112 25538595.65174283] 
[25317284.31091545 25223539.66363661 25272235.85780019 25551426.21236818 25467989.425944 ] 
[25327294.06390036 25527840.32567072 25499601.14864586 25657214.623082 25527855.25691375]]
不使用:3.2115318500000285

現(xiàn)在來看看 CuPy。代碼幾乎一樣;只需更改頂部的導(dǎo)入,并將 cp 替換為 np!

import cupy as cp 

# 設(shè)置種子以實(shí)現(xiàn)可重復(fù)性
cp.random.seed(0) 

# 生成兩個(gè) 2000x2000 的隨機(jī)浮點(diǎn)數(shù)數(shù)組,范圍在 1 到 100 之間
A = cp.random.uniform(low=1.0, high=100.0, size=(10000 , 10000)) 
B = cp.random.uniform(low=1.0, high=100.0, size=(10000 , 10000)) 

# 執(zhí)行矩陣乘法
start = timer() 
C = cp.matmul(A, B) 
# 等待所有計(jì)算完成
cp.cuda.Stream.null.synchronize() 


# 由于矩陣很大,將它們?nèi)看蛴〕鰜聿⒉粚?shí)際。
# 相反,你可以打印結(jié)果的形狀和一小部分以進(jìn)行驗(yàn)證。
print("結(jié)果矩陣的一小部分:\n", C[:5 , :5]) 
print("使用 GPU:", timer()-start)
結(jié)果矩陣的一小部分:
[[25710603.94664048 25421109.27794836 25400571.17687622 25165215.05626292 25729646.95638799] 
[25625453.16519611 25144442.91475235 25222187.53040171 25345612.79231448 25740855.19128766] 
[25341043.05541366 25193877.59648657 25213287.79042915 25105198.56650982 25697665.56022939] 
[25747476.4063573 25303358.1864255 25188271.28090249 25260575.16770762 25653182.98191385] 
[25775006.9423866 25390991.70257155 25475701.8092414 25170055.16207211 25525589.5144844 ]]
使用 GPU:3.991562336000243

等一下!發(fā)生了什么?CuPy 代碼比 Numpy 代碼運(yùn)行時(shí)間更長(zhǎng)。這是怎么回事?

我承認(rèn)我花了一些時(shí)間才弄清楚,但最終還是歸結(jié)于內(nèi)存。當(dāng)我們將隨機(jī)浮點(diǎn)值分配給數(shù)組時(shí),它們默認(rèn)設(shè)置為 64 位值。

A.dtype 
dtype( 'float64' )

似乎大多數(shù) GPU 都使用 32 位內(nèi)存寄存器,因此當(dāng)它們處理 64 位數(shù)字時(shí),它們必須做額外的工作,因?yàn)槊總€(gè)數(shù)字都會(huì)分布在兩個(gè)內(nèi)存位置上。至少我是這么認(rèn)為的。如果有人知道更詳細(xì)的信息,請(qǐng)?jiān)u論告訴我。

現(xiàn)在看看如果我們把數(shù)字的數(shù)據(jù)類型改為 float32 會(huì)發(fā)生什么。所以我把這兩行代碼改了

A = np.random.uniform(low= 1.0 , high= 100.0 , size=( 10000 , 10000 )) 
B = np.random.uniform(low= 1.0 , high= 100.0 , size=( 10000 , 10000 ))

to

A = np.random.uniform(low= 1.0 , high= 100.0 , size=( 10000 , 10000 )).astype(np.float32) 
B = np.random.uniform(low= 1.0 , high= 100.0 , size=( 10000 , 10000 )).astype(np.float32) 

AND 

A = cp.random.uniform(low= 1.0 , high= 100.0,size=( 10000 , 10000 )) 
B = cp.random.uniform(low= 1.0 , high= 100.0 , size=( 10000 , 10000 ))

to

A = cp.random.uniform(low= 1.0 , high= 100.0 , size=( 10000 , 10000 )).astype(cp.float32) 
B = cp.random.uniform(low= 1.0 , high= 100.0 , size=( 10000 , 10000 )).astype(cp.float32)

我重新運(yùn)行了兩組代碼,以下是輸出。先用 Numpy。

結(jié)果矩陣的一小部分:
[[25461280. 25168348. 25212528. 25303310. 25277886.] 
[25114762. 25197556. 25340074. 25341846. 25373122.] 
[25381818. 25326516. 25438612. 25596934. 25538596.] 
[25317284. 25223536. 25272240. 25551426. 25467992.] 
[25327292. 25527844. 25499604. 25657220. 25527856.]]
不使用 GPU:1.8297855099999651

因此,Numpy 的運(yùn)行時(shí)間幾乎減少了一半,這并不奇怪,因?yàn)閮?nèi)存需求也減少了一半。

現(xiàn)在看看 CuPy 運(yùn)行會(huì)發(fā)生什么。

結(jié)果矩陣的一小部分:
[[25710616. 25421130. 25400568. 25165210. 25729658.] 
[25625414. 25144374. 25222220. 25345620. 25740910.] 
[25341046. 25193884. 25213314. 25105278. 25697658.] 
[25747516. 25303340. 25188230. 25260598. 25653224.] 
[25775088. 25390888. 25475664. 25170094. 25525540.]]
使用 GPU: 0.14140109800064238

這真是令人印象深刻。不到 0.15 秒的運(yùn)行時(shí)間意味著比 Numpy 快了 10 倍以上。別忘了,NumPy 已經(jīng)超級(jí)快了!

我想,歸根結(jié)底,如果你真的需要處理 64 位數(shù)值數(shù)組,那么如果你的 GPU 只支持 32 位內(nèi)存,那么使用 GPU 可能并沒有什么優(yōu)勢(shì)。隨著時(shí)間的推移,更新、更強(qiáng)大的 GPU 可能會(huì)轉(zhuǎn)向 64 位內(nèi)存寄存器。高端 GPU 可能已經(jīng)這么做了。

例3

結(jié)合 CPU 和 GPU 代碼。

有時(shí),并非所有處理都能在 GPU 上完成。一個(gè)常見的用例是繪制數(shù)據(jù)圖表。當(dāng)然,你可以使用 GPU 處理數(shù)據(jù),但通常,下一步是查看最終數(shù)據(jù)集的樣子。如果數(shù)據(jù)駐留在 GPU 內(nèi)存中,則無法繪制數(shù)據(jù),因此在調(diào)用繪圖函數(shù)之前,你需要將其移回 CPU 內(nèi)存。將大量數(shù)據(jù)從 GPU 移動(dòng)到 CPU 是否值得?

現(xiàn)在來一探究竟。

在此示例中,我有一個(gè)簡(jiǎn)單的 CSV 文件,其中包含日期列和 2016 年至 2018 年的用電量列。我想計(jì)算這些日期的用電量平均值、最小值和最大值,然后使用 matplotlib 繪制這些數(shù)據(jù)。這是前幾行的樣子。該文件總共有近 1200 萬條記錄。

DATE,USAGE
10/22/2016,0.01
10/22/2016,0.01
10/22/2016,0.01
10/22/2016,0.01
10/22/2016,0.01
10/22/2016,0.01
10/22/2016,0.01
10/22/2016,0.01
10/22/2016,0.02
10/22/2016,0.02
10/22/2016,0.02
10/22/2016,0.02
10/22/2016,0.01
...
...

以下是使用常規(guī) CPU 代碼執(zhí)行此操作的一種方法。

from timeit import default_timer as timer
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import datetime

# 假設(shè) df 是讀取 CSV 后的 DataFrame
 df = pd.read_csv( '/mnt/d/test/D202.csv' , sep= ',' ) 

start = timer() 
df[ 'DATE' ] = pd.to_datetime(df[ 'DATE' ]).dt.date 

# 將 'USAGE' 轉(zhuǎn)換為 NumPy 數(shù)組
usage = df[ 'USAGE' ].values 

# 將 'DATE' 轉(zhuǎn)換為 NumPy 數(shù)組
dates = np.array([date.toordinal() for date in df[ 'DATE' ]]) 

# 查找唯一日期及其索引
unique_dates, indices = np.unique(dates, return_inverse= True ) 

# 初始化數(shù)組來保存最大值、最小值和平均值
max_usage = np.zeros( len (unique_dates)) 
min_usage = np.zeros( len (unique_dates)) 
mean_usage = np.zeros( len (unique_dates)) 

# 計(jì)算每個(gè)組的最大值、最小值和平均值
for i, date in  enumerate (unique_dates): 
    max_usage[i] = np.max ( usage[indices == i]) 
    min_usage[i] = np. min (usage[indices == i]) 
    mean_usage[i] = np.mean(usage[indices == i]) 

# 將序數(shù)日期轉(zhuǎn)換為日期時(shí)間進(jìn)行繪圖
plot_dates = [datetime.date.fromordinal(date) for date in unique_dates] 

# Plotting
plt.figure(figsize=(10, 6))
plt.plot(plot_dates, mean_usage, label='Mean Usage', marker='o')
plt.plot(plot_dates, max_usage, label='Max Usage', marker='x')
plt.plot(plot_dates, min_usage, label='Min Usage', marker='+')
plt.xlabel('Date')
plt.ylabel('Usage (kWh)')
plt.title('Electric Usage Statistics by Date')
plt.legend()
plt.xticks(rotatinotallow=45)
plt.tight_layout()
plt.show()
print("Finished with CPU at ", timer()-start)

圖片圖片

這是 GPU 等效代碼。

from timeit import default_timer as timer
import pandas as pd
import numpy as np
import cupy as cp
import matplotlib.pyplot as plt
import datetime


# 假設(shè) df 是讀取 CSV 后的 DataFrame
df = pd.read_csv('/mnt/d/test/D202.csv' , sep=',' ) 

start = timer() 
df['DATE'] = pd.to_datetime(df['DATE']).dt.date 

# 將 'USAGE' 轉(zhuǎn)換為 CuPy 數(shù)組
usage = cp.array(df['USAGE'].values) 

# 將 'DATE' 轉(zhuǎn)換為 NumPy 數(shù)組(因?yàn)槿掌谔幚聿皇?CuPy 功能)
dates = np.array([date.toordinal() for date in df['DATE']]) 

# 使用 NumPy 查找唯一日期及其索引
# (CuPy 不支持帶有 return_inverse 的 np.unique)
unique_dates, indices = np.unique(dates, return_inverse=True) 

# 初始化數(shù)組以保存 GPU 上的最大值、最小值和平均值
max_usage = cp.zeros(len(unique_dates), dtype=cp.float64) 
min_usage = cp.zeros(len(unique_dates), dtype=cp.float64) 
mean_usage = cp.zeros(len(unique_dates), dtype=cp.float64) 

# 使用 CuPy 計(jì)算每個(gè)組的最大值、最小值和平均值
for i, date in enumerate(unique_dates): 
    mask = indices == i 
    max_usage[i] = cp.max(usage[mask]) 
    min_usage[i] = cp.min(usage[mask]) 
    mean_usage[i] = cp.mean(usage[mask]) 

# 等待計(jì)算完成
cp.cuda.Stream.null.synchronize() 

# 由于 CuPy 不支持繪圖和日期轉(zhuǎn)換,
# 請(qǐng)將結(jié)果轉(zhuǎn)換回 NumPy 以完成這些任務(wù)
max_usage = cp.asnumpy(max_usage) 
min_usage = cp.asnumpy(min_usage) 
mean_usage = cp.asnumpy(mean_usage) 
plot_dates = [datetime.date.fromordinal(date) for date in unique_dates] 

# 繪圖
plt.figure(figsize=(10, 6))
plt.plot(plot_dates, mean_usage, label='Mean Usage', marker='o')
plt.plot(plot_dates, max_usage, label='Max Usage', marker='x')
plt.plot(plot_dates, min_usage, label='Min Usage', marker='+')
plt.xlabel('Date')
plt.ylabel('Usage (kWh)')
plt.title('Electric Usage Statistics by Date')
plt.legend()
plt.xticks(rotatinotallow=45)
plt.tight_layout()
plt.show()
print("Finished with GPU at ", timer()-start)

圖片

這兩組代碼集之間唯一真正的區(qū)別是這 3 行,我們?cè)诶L制 CuPy 數(shù)組數(shù)據(jù)之前將其從 GPU 復(fù)制到 CPU。

max_usage = cp.asnumpy(max_usage)
min_usage = cp.asnumpy(min_usage)
mean_usage = cp.asnumpy(mean_usage)

即便如此,CuPy 代碼也比 NumPy 代碼快 70%,因此在這種情況下,這些額外的數(shù)據(jù)復(fù)制步驟的開銷是值得的。

無論如何,我希望本文能夠激發(fā)你研究在工作負(fù)載中使用 CuPy 庫和 GPU 的興趣。

記住要測(cè)試、測(cè)試、再測(cè)試。并非所有工作負(fù)載都能從切換到基于 GPU 的代碼中受益。有時(shí),你的代碼運(yùn)行速度可能會(huì)變慢,或者任何好處都微不足道,甚至不值得付出努力去實(shí)現(xiàn)。嘗試使用 CuPy 代替 NumPy 的一個(gè)好處是操作起來很容易。即使它沒有用,你也不會(huì)浪費(fèi)太多時(shí)間。

責(zé)任編輯:武曉燕 來源: 數(shù)據(jù)STUDIO
相關(guān)推薦

2021-07-27 10:10:21

CuPyNumpyPython

2023-03-22 13:53:26

芯片英偉達(dá)

2024-09-12 22:45:47

2015-03-19 11:03:49

Linuxwin10

2024-11-13 09:29:41

SpringCRaCCRIU

2024-03-19 14:43:17

自動(dòng)駕駛激光

2022-10-14 17:30:59

Windows 11微軟

2021-01-13 16:04:07

網(wǎng)絡(luò)On-Prem托管

2017-12-06 08:06:47

IBMGPU機(jī)器學(xué)習(xí)

2023-10-14 15:22:22

2014-09-28 10:29:43

喬布斯施密特Android

2021-12-23 15:36:21

NASSANDAS

2023-05-22 19:49:30

命令Linux

2020-08-25 09:14:17

對(duì)象存儲(chǔ)文件存儲(chǔ)塊存儲(chǔ)

2021-02-19 18:10:06

微軟WindowsWindows 10

2021-02-19 23:44:27

Windows 10Windows微軟

2021-09-30 11:27:58

模型人工智能神經(jīng)網(wǎng)絡(luò)

2019-04-02 15:07:51

API NginxZuul

2011-07-01 10:11:39

2025-02-18 16:00:00

代碼Python架構(gòu)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

欧美理论电影在线播放| 欧美日韩国产综合新一区| 成人国产精品色哟哟| 久草中文在线视频| 亚洲尤物av| 欧美一区二区三区色| jizzjizz国产精品喷水| 日本成人一区| 日韩黄色在线观看| 欧美国产日韩xxxxx| 波多野结衣a v在线| 国产精品日本一区二区不卡视频| 精品国产1区2区| 在线观看日本一区| 亚洲av成人无码久久精品老人 | 国产视频在线观看一区二区| 视频在线观看免费高清| 涩涩视频在线播放| 亚洲精品高清在线| 视频二区一区| 日韩专区第一页| 麻豆国产精品一区二区三区| 久久久亚洲福利精品午夜| 手机免费观看av| 免费毛片在线不卡| 亚洲国产欧美一区| 性鲍视频在线观看| 欧美成人aaa| 色成年激情久久综合| 成年丰满熟妇午夜免费视频| 91精彩视频在线观看| 91天堂素人约啪| 国产精品果冻传媒潘| 国产精品爽爽久久| 另类欧美日韩国产在线| 国产成人亚洲精品| 人妻丰满熟妇av无码区| 在线亚洲一区| 韩国日本不卡在线| 久久精品国产亚洲AV无码麻豆| 国产精品久久久久久久免费观看 | 亚洲第一黄色| 欧美成人精品在线视频| 亚洲欧洲综合网| 成人久久一区| 中文字幕亚洲欧美日韩在线不卡 | 日本久久一二三四| 亚洲天堂色网站| 久久久视频6r| 欧美日韩亚洲在线观看| 在线a欧美视频| 久久久久亚洲AV成人无在| 国产精品最新| 亚洲欧美日韩第一区| 法国伦理少妇愉情| 欧美猛男同性videos| 国产午夜精品一区理论片飘花| 免费在线观看污| 精品国产aⅴ| 正在播放国产一区| 中文字幕资源站| 欧美成人精品| 欧美极品少妇xxxxx| 亚洲精品午夜久久久久久久| av成人激情| 国产91精品最新在线播放| 91黑人精品一区二区三区| 视频精品一区二区| 国产精品久久久久久久久借妻| 中文字幕欧美人妻精品一区蜜臀| 人妖欧美一区二区| 91亚洲永久免费精品| 国产黄色一级大片| 成人国产亚洲欧美成人综合网| 国产精品久久久一区二区三区| 手机在线精品视频| 久久久91精品国产一区二区三区| 色一情一区二区三区四区| 婷婷激情在线| 夜夜嗨av一区二区三区四季av| 国产妇女馒头高清泬20p多| 天堂√8在线中文| 欧美三级视频在线| 在线播放第一页| 九九热精品视频在线观看| 色先锋资源久久综合5566| 黄色一级视频免费| 六月天综合网| 91在线观看免费| 天天躁日日躁狠狠躁伊人| 亚洲国产高清在线| 亚洲熟妇无码av在线播放| 国产不卡网站| 欧美一级在线免费| 免费看污片网站| 亚洲五月综合| 日本精品久久久| 99久久婷婷国产一区二区三区| 成人黄色在线网站| 亚洲人成77777| 男人的天堂免费在线视频| 欧美日韩国产小视频| 一级欧美一级日韩片| 日韩中文欧美| 久久久亚洲影院| 亚洲综合免费视频| 337p粉嫩大胆噜噜噜噜噜91av| 水蜜桃一区二区三区| 大桥未久在线播放| 91精品国产综合久久精品 | 久久久久97| 最近中文字幕2019免费| 五月天综合激情| 国产精品一级片在线观看| 日本在线免费观看一区| av小说在线播放| 678五月天丁香亚洲综合网| www.超碰97| 亚洲福利免费| 99在线视频播放| 九七久久人人| 欧美三级电影在线看| 无码h肉动漫在线观看| 好看的亚洲午夜视频在线| 国产精品夜间视频香蕉| 蜜芽tv福利在线视频| 亚洲成人综合网站| 四虎国产精品永久免费观看视频| 欧洲乱码伦视频免费| 欧美中文在线免费| 亚洲欧美丝袜中文综合| 亚洲午夜在线观看视频在线| 乳色吐息在线观看| 久久久久午夜电影| 91精品视频在线看| 国产在线一区二区视频| 欧美精品九九99久久| 自拍偷拍第9页| 麻豆成人综合网| 亚洲精品第一区二区三区| 久久久成人av毛片免费观看| 亚洲视频在线免费观看| 91青青草视频| 国产调教视频一区| 99久久激情视频| 精品久久国产| 国产精品免费久久久久久| 不卡在线视频| 欧美精品日韩一本| 四虎精品免费视频| 国产盗摄一区二区三区| 大陆极品少妇内射aaaaaa| 538任你躁精品视频网免费| 欧美黑人性猛交| 国内爆初菊对白视频| 国产美女网站视频| 国产一区二区成人久久免费影院| 国产又黄又爽免费视频| 麻豆精品一区| 国内揄拍国内精品| 青青免费在线视频| 欧美在线观看你懂的| av片在线免费看| 国产一区二区三区四| 精品视频在线观看一区二区| 一区二区三区四区高清视频| 国内精品久久久久久影视8| 亚洲aaaaaaa| 欧美在线观看视频一区二区三区| 女人18毛片毛片毛片毛片区二| 国产主播一区二区| 日本福利视频一区| 免费不卡中文字幕在线| 国产欧美亚洲视频| 青草视频在线免费直播 | 中文字幕在线视频区| 欧美精品第1页| 久久久久久久久99| 久久久精品国产免大香伊| 污色网站在线观看| 伊人久久亚洲热| 欧美日韩一区二区视频在线观看 | 亚洲妇熟xxxx妇色黄| 日韩电影在线观看中文字幕 | 国产成人在线观看网站| 久久精品欧美日韩精品| 永久免费黄色片| 亚洲视频成人| 亚洲美女自拍偷拍| 青青操综合网| 91久久嫩草影院一区二区| 91九色美女在线视频| 在线成人免费网站| 欧美视频xxx| 欧美日韩日日夜夜| 国产精品黄色网| 亚洲婷婷综合久久一本伊一区| 好吊色视频一区二区三区| 欧美a一区二区| 免费观看美女裸体网站| 久久电影院7| 久久精品午夜一区二区福利| 免费观看性欧美大片无片| 日韩av大片免费看| 黄色影院在线看| 日韩亚洲精品电影| 欧美精品久久久久久久久久丰满| 3751色影院一区二区三区| www.国产一区二区| 一二三区精品视频| 777777国产7777777| 久久久久久久一区| www.日本高清| 国产成人啪免费观看软件| 小泽玛利亚视频在线观看| 国产欧美在线| 日韩国产成人无码av毛片| 国产高清久久| 三级三级久久三级久久18| 免费看久久久| 99在线视频首页| 亚洲青青久久| 国产美女扒开尿口久久久| 欧美黑人粗大| 欧美又大粗又爽又黄大片视频| 久久免费电影| 欧美老少做受xxxx高潮| 福利视频在线| 日韩视频一区在线| aaa在线观看| 亚洲片国产一区一级在线观看| 深爱激情五月婷婷| 日韩av一区在线观看| 黄色片一区二区| 精品国产乱码久久久久久久| 国产黄频在线观看| 日韩久久久久久| 亚洲AV无码乱码国产精品牛牛| 91精品国产综合久久精品 | 激情成人综合网| 日本高清久久久| 韩日精品视频一区| 波多野结衣在线免费观看| 热久久国产精品| 少妇网站在线观看| 蜜臀av一区二区在线观看| 永久免费的av网站| 久久国产乱子精品免费女| 天天干天天爽天天射| 麻豆国产欧美一区二区三区| 涩涩网站在线看| 国产在线视频一区二区| √天堂资源在线| 国产成人在线视频网站| 欧美激情一区二区三区p站| 成人激情免费电影网址| 添女人荫蒂视频| 国产日韩精品一区| 黄色裸体一级片| 一区二区三区精品久久久| 麻豆视频在线观看| 韩曰欧美视频免费观看| 国产女优在线播放| 日韩一区二区在线观看| 欧美一区,二区| 亚洲午夜小视频| 欧美日韩在线资源| 九九热99久久久国产盗摄| 国产高清视频色在线www| 国产成人+综合亚洲+天堂| 国产精品第一国产精品| 亚洲在线免费观看| 欧美日韩导航| 亚洲午夜精品一区二区三区| 亚洲精品小说| 日本少妇高潮喷水视频| 免费精品视频在线| 图片区偷拍区小说区| 久久精品人人做人人爽97| 永久免费看片直接| 性做久久久久久| 在线观看国产精品入口男同| 精品少妇一区二区三区免费观看 | 色网站在线视频| av一区二区久久| 国精品人伦一区二区三区蜜桃| 亚洲一区二区三区小说| 青青国产在线视频| 日韩免费高清视频| 电影在线一区| 欧美激情久久久| 日本一区免费网站| 国产乱码一区| 91亚洲自偷观看高清| 3d动漫一区二区三区| 久久国产精品露脸对白| 国产精品久久不卡| 中文字幕综合网| 亚洲 日本 欧美 中文幕| 日韩欧美一区二区三区在线| 国产主播福利在线| 午夜免费日韩视频| 国产乱码精品一区二区三区亚洲人| 久久国产精品久久精品国产| 婷婷精品进入| 欧美国产日韩在线播放| 风间由美一区二区三区在线观看| 超碰97av在线| 色婷婷综合久久久久中文一区二区 | 18免费在线视频| 欧日韩不卡在线视频| 亚洲专区**| 久久精品国产精品亚洲精品色 | 男男受被啪到高潮自述| 日本一区二区三区四区| 影音先锋亚洲天堂| 欧美mv和日韩mv的网站| 麻豆视频在线免费观看| 日本欧美精品在线| 久久香蕉网站| 99在线精品免费视频| 国产成人日日夜夜| www青青草原| 91精品国产一区二区三区香蕉| h视频网站在线观看| 欧美一二三视频| 欧美激情影院| 男人添女人下面高潮视频| 成人毛片视频在线观看| 激情综合网五月天| 91麻豆精品国产91久久久资源速度 | av电影天堂一区二区在线 | 亚洲精一区二区三区| 久草视频福利在线| 亚洲成在人线免费| 色综合视频在线| 97免费中文视频在线观看| 超碰地址久久| 成年人网站免费视频| a亚洲天堂av| 久久免费激情视频| 日韩成人在线免费观看| 国产免费拔擦拔擦8x高清在线人| 国产伦精品一区| 在线视频免费在线观看一区二区| 黄色av网址在线观看| 欧美日韩一区二区在线播放| 人成在线免费视频| 国产精品99久久99久久久二8| 免费电影一区二区三区| 中文字幕永久视频| 亚洲国产岛国毛片在线| 在线观看国产小视频| 久久人人爽人人爽人人片亚洲| av成人在线网站| 亚洲精品天堂成人片av在线播放| 东方aⅴ免费观看久久av| 国产乡下妇女做爰| 日韩av一区在线| 成人交换视频| 三级网在线观看| 成人h版在线观看| 天天干在线播放| 永久免费毛片在线播放不卡| 欧美一级做a| 欧美这里只有精品| 91网站视频在线观看| 最近中文字幕av| 久久国产精品影视| 欧美日韩一区二区三区在线电影 | 91麻豆天美传媒在线| 成人免费视频网站在线观看| 啦啦啦免费高清视频在线观看| 一本色道久久综合亚洲精品小说 | wwwwww欧美| 97精品国产露脸对白| 在线观看黄色网| 欧美激情亚洲国产| 国产精品羞羞答答在线观看| 九九热精品在线播放| 亚洲成av人片在线观看无码| 国内精品一区视频| 91原创国产| 日韩福利视频导航| 久久艹精品视频| 中日韩美女免费视频网址在线观看 | 在线免费看视频| 亚洲成人999| 久久久加勒比| 怡红院av亚洲一区二区三区h| 中文字幕精品在线不卡| 亚洲成a人片在线| 国产精品久久久久久久app| 狠狠综合久久| 成人精品一二三区| 日韩国产激情在线| 美女久久精品| 艹b视频在线观看| 欧美日韩国产页| 手机在线免费观看av|