2011-03-27 113 views
5

我使用CUBLAS(Cuda Blas庫)進行矩陣操作。CUBLAS - 矩陣元冪可能嗎?

是否可以使用CUBLAS來實現矩陣項的冪指數/均方根?

我的意思是,將具有2×2矩陣

1 4 
9 16 

我想是提高到給定值例如一個功能2

1 16 
81 256 

並計算均方根例如

1 2 
3 4 

CUBLAS這可能嗎?我找不到適合這個目標的函數,但我會先問這裏,開始編寫我自己的內核。

+2

注意,這不是矩陣求冪(也不是均方根)。您只是對各個元素執行標量操作。 – 2011-03-27 15:06:44

+0

不好意思,是的,我需要執行這樣的操作 – 2011-03-27 15:15:11

+0

我已經更新了相應的問題標題。 – 2011-03-27 15:21:21

回答

9

所以這可能是你必須自己實施,因爲圖書館不會爲你做。 (可能有一些方法可以用BLAS 3級例程實現它 - 當然是矩陣元素的平方 - 但它會涉及昂貴的和其他不必要的矩陣向量乘法,而且我仍然不知道你是如何「 d做平方根操作)。原因是這些操作不是真正的線性代數過程;取每個矩陣元素的平方根並不真正對應於任何基本的線性代數運算。

好消息是,這些元素操作在CUDA中非常簡單。再說一次,爲了獲得最佳性能,可以使用很多調整選項,但可以很容易地開始。與矩陣加法運算一樣,在這裏將N×M矩陣作爲(N×M)長度向量處理;對於這些元素操作,矩陣的結構並不重要。因此,您將傳遞一個指向矩陣第一個元素的指針,並將其作爲單個N * M個數列表處理。 (我要你用float這兒的假設,因爲你在談論SGEMMSAXPY更早。)

內核,CUDA的實際代碼位,它實現了操作,很簡單。現在,每個線程將計算一個數組元素的平方(或平方根)。 (無論這是最佳的還是不是性能的,都可以測試)。所以內核將如下所示。我假設你正在做類似B_ij =(A_ij)^ 2;如果你想要做的就地操作,如A_ij =(A_ij)^ 2,你能做到這一點,太:

__global__ void squareElements(float *a, float *b, int N) { 
    /* which element does this compute? */ 
    int tid = blockDim.x * blockIdx.x + threadIdx.x; 

    /* if valid, squre the array element */ 
    if (tid < N) 
      b[tid] = (a[tid]*a[tid]); 
} 

__global__ void sqrtElements(float *a, float *b, int N) { 
    /* which element does this compute? */ 
    int tid = blockDim.x * blockIdx.x + threadIdx.x; 

    /* if valid, sqrt the array element */ 
    if (tid < N) 
      b[tid] = sqrt(a[tid]); /* or sqrtf() */ 
} 

請注意,如果你真行非常略有增加錯誤,「sqrtf() '最大誤差爲3 ulp的函數(最後一個單元)顯着更快。

你如何調用這些內核將取決於你在做什麼的順序。如果您已經在這些基礎上進行了一些CUBLAS調用,那麼您需要在已經存在於GPU內存中的陣列上使用它們。

+0

非常感謝Jonathan,你寫了太多的東西來幫助我。 我仍然想知道如何實現一些稍微微妙的細節(塊/線程的數量,如何最大化聚結,ecc ..),但我會試一試,並有一些測試運行第一。 如果我有其他疑問,我會發布另一個問題 再次感謝您的幫助! – 2011-03-27 18:06:59

+1

User @solvingpuzzles正確地指出我在上面的代碼中使用的'block_id'當然應該是'blockIdx.x';我不知道爲什麼我把'block_id'放在那裏。 – 2012-10-26 14:20:24