0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

基于cutlass GTC2020的slides

jf_pmFSk4VX ? 來源:GiantPandaCV ? 2024-01-04 16:28 ? 次閱讀

what are tensorcores

a164fdfc-aa37-11ee-8b88-92fbcf53809c.png

TensorCore是一個硬件概念,主要是用于加速矩陣乘操作運算(我們也叫MMA,Matrix Multiply Add),執(zhí)行的是:

D = A * B + C

同時也支持多種輸入類型,數(shù)值累加類型。

a183b3a0-aa37-11ee-8b88-92fbcf53809c.png

編程層次上,TensorCore處于Warp(連續(xù)的32個threads)這一層,一個WARP內(nèi)持有A, B, C, D四個操作數(shù)的數(shù)據(jù)。

a19a1802-aa37-11ee-8b88-92fbcf53809c.png

上圖是Ampere架構(gòu)支持的MMA指令,支持多種尺寸,數(shù)據(jù)類型。

Slides下面就是介紹各種尺寸的MMA,我們可以結(jié)合代碼跑一下

S8 * S8 + S32 Code

使用TensorCore的時候,對數(shù)據(jù)排布是有特殊要求的。MMA指令是在一個WARP內(nèi)執(zhí)行,所以各個線程對應取數(shù)據(jù)的位置也是有特殊的映射關(guān)系。

首先來個簡單的 int8 x int8 = int32 的(8x16 matmul 16x8 = 8x8)運算,Slides里的排布是這樣:

a1b71d80-aa37-11ee-8b88-92fbcf53809c.png

每個線程持有 A的4x8bit = 32bit 數(shù)據(jù),B的4x8bit = 32bit 數(shù)據(jù),C/D的 2x32bit = 64bit 數(shù)據(jù)

我們假設(shè)使用的矩陣為:

a1dae51c-aa37-11ee-8b88-92fbcf53809c.png

我們把線程映射跟元素寫到一塊:

a208a006-aa37-11ee-8b88-92fbcf53809c.png

而由于tensor core instruction is TN layout.

這里還是沿用blas計算庫的說法,blas庫里,會將 a x b = c -> b_T x a_T = c_T,這里的T說的是B矩陣是transpose的,也即A矩陣是RowMajor, B矩陣是ColMajor.

所以實際上應該是:

a230b014-aa37-11ee-8b88-92fbcf53809c.png

可以看到跟A矩陣是完全一樣了,后面取元素的時候兩個矩陣寄存器所使用的index是一致的

這里使用的代碼是slides里的example。

a24e7fcc-aa37-11ee-8b88-92fbcf53809c.png

先簡單寫個初始化的kernel:

#include"stdio.h"
#include"stdint.h"

__global__voidset_value(int8_t*x,int32_telem_cnt){
for(inti=0;i(i%8);
}
}

接下來是TensorCore運算的kernel,需要注意的是這里用的都是int32類型,而我們執(zhí)行的是 s8 x s8 = s32 的計算,調(diào)用的時候需要reinterpret_cast下。

//DoAxB+C=D.
__global__voidtensor_core_example_8x8x16(int32_t*D,
uint32_tconst*A,
uint32_tconst*B,
int32_tconst*C){
//ComputethecoordinatesofaccessestoAandBmatrices
intouter=threadIdx.x/4;//morndimension
intinner=threadIdx.x%4;//kdimension
//Computethecoordinatesfortheaccumulatormatrices
intc_row=threadIdx.x/4;
intc_col=2*(threadIdx.x%4);
//Computelinearoffsetsintoeachmatrix
intab_idx=outer*4+inner;
intcd_idx=c_row*8+c_col;

//IssueTensorCoreoperation
asmvolatile("mma.sync.aligned.m8n8k16.row.col.s32.s8.s8.s32{%0,%1},{%2},{%3},{%4,%5};
"
:"=r"(D[cd_idx]),"=r"(D[cd_idx+1])
:"r"(A[ab_idx]),"r"(B[ab_idx]),"r"(C[cd_idx]),"r"(C[cd_idx+1]));
}
最后打印輸出結(jié)果:
__global__voidprintMatrix(int32_t*result,constintm,constintn){
for(introw=0;row>>(a,m*k);
set_value<<<1,?1>>>(b,k*n);
cudaMemset(c,0,sizeof(int32_t)*m*n);
cudaMemset(d,0,sizeof(int32_t)*m*n);

tensor_core_example_8x8x16<<<1,?32>>>(reinterpret_cast(d),
reinterpret_cast(a),
reinterpret_cast(b),
reinterpret_cast(c));

printMatrix<<<1,?1>>>(d,m,n);
cudaDeviceSynchronize();
cudaFree(a);
cudaFree(b);
cudaFree(c);
cudaFree(d);
}

舉一反三

下面我們也可以舉一反三,寫下 f16*f16+fp32的 tensorcore程序,對應的指令是 16 x 8 x 8,不過線程持有的數(shù)據(jù)跟前面的例子有些不同,需要改下

a28d0c6a-aa37-11ee-8b88-92fbcf53809c.png

#include"stdio.h"
#include"stdint.h"
#include"cuda_fp16.h"

template
__global__voidset_value(T*x,int32_telem_cnt){
for(inti=0;i(i%8);
}
}

__global__voidtensor_core_example_16x8x8(float*D,
uint32_tconst*A,
uint32_tconst*B,
floatconst*C){
//ComputethecoordinatesofaccessestoAandBmatrices
intouter=threadIdx.x/4;//morndimension
intinner=threadIdx.x%4;//kdimension
//Computethecoordinatesfortheaccumulatormatrices
intc_row=threadIdx.x/4;
intc_col=2*(threadIdx.x%4);
//Computelinearoffsetsintoeachmatrix
intab_idx=outer*4+inner;
intcd_idx=c_row*8+c_col;

//IssueTensorCoreoperation
asmvolatile("mma.sync.aligned.m16n8k8.row.col.f32.f16.f16.f32{%0,%1,%2,%3},{%4,%5},{%6},{%7,%8,%9,%10};
"
:"=f"(D[cd_idx]),"=f"(D[cd_idx+1]),"=f"(D[cd_idx+64]),"=f"(D[cd_idx+1+64])
:
"r"(A[ab_idx]),"r"(A[ab_idx+32]),
"r"(B[ab_idx]),
"f"(C[cd_idx]),"f"(C[cd_idx+1]),"f"(C[cd_idx+64]),"f"(C[cd_idx+1+64])
);
}

__global__voidprintMatrix(float*result,constintm,constintn){
for(introw=0;row(result[row*n+col]));
}
printf("
");
}
}

intmain(){
half*a;
half*b;
float*c;
float*d;

constint32_tm=16;
constint32_tk=8;
constint32_tn=8;

cudaMalloc(&a,m*k*sizeof(half));
cudaMalloc(&b,k*n*sizeof(half));
cudaMalloc(&c,m*n*sizeof(float));
cudaMalloc(&d,m*n*sizeof(float));

set_value<<<1,?1>>>(a,m*k);
set_value<<<1,?1>>>(b,k*n);
cudaMemset(c,0,sizeof(float)*m*n);
cudaMemset(d,0,sizeof(float)*m*n);

tensor_core_example_16x8x8<<<1,?32>>>(reinterpret_cast(d),
reinterpret_cast(a),
reinterpret_cast(b),
reinterpret_cast(c));

printMatrix<<<1,?1>>>(d,m,n);
cudaDeviceSynchronize();
cudaFree(a);
cudaFree(b);
cudaFree(c);
cudaFree(d);
}

可以看到不同的MMA指令會對應不同的矩陣規(guī)模,不同的數(shù)據(jù)類型。在CUTLASS,上述的這些MMA被統(tǒng)一到一個模板里:

a2a0ea00-aa37-11ee-8b88-92fbcf53809c.png

實際使用的話,只需對應實例化MMA模板即可:

a2c3b792-aa37-11ee-8b88-92fbcf53809c.png

DATA Movement

下面幾張Slides談?wù)摰氖蔷仃嚦酥袛?shù)據(jù)搬運的部分,以及新架構(gòu)引入的LDMatrix指令。

a2d7a81a-aa37-11ee-8b88-92fbcf53809c.png

這張Slide還是以S8 x S8 + S32的mma為例,前面我們也推導過,一個WARP完成 8x16 matmul 16x8, 那么一個WARP加載A矩陣和B矩陣一共需要 (8x16 + 16x8) = 256B,F(xiàn)LOPS計算如下:

C矩陣一共8*8=64個元素
每個元素需要16次乘法和加法,
FLOPS=64*16*2=2048

兩者一除得到計算訪存比為 8flops/byte。

那么我們再看下Ampere架構(gòu)白皮書里面標注的設(shè)計規(guī)格,A100的Int8 tensorcore算力是624TFLOPS(312是FP16,int8對應翻一倍),80GB A100的HBM速度為1.6TB/s,那么其理想計算訪存比是 400flops/byte

相較兩者訪存比,可以看到使用了TensorCore后,訪存成為了瓶頸,這也是為什么數(shù)據(jù)搬運在優(yōu)化GEMM里是很重要的一環(huán)。

這里我覺得是作為一種理想情況的估算,實際情況可能更復雜,需要考慮緩存命中率等(參考知乎李少俠的文章)

因此cutlass抽象了一套高效的數(shù)據(jù)搬運流程,過往很多GEMM優(yōu)化文章都有介紹,就不贅述了:

a2ee7c7a-aa37-11ee-8b88-92fbcf53809c.png

其中在Ampere架構(gòu)里面,新引入了AsyncCopy機制,也就是在Global Memory 到 SharedMemory 這一個環(huán)節(jié)。以往我們需要從Global Memory讀取到線程寄存器,再從寄存器里存儲到SharedMemory,但有了這個指令后,我們可以一步到位,從GlobalMemory -> SharedMemory,一定程度減輕了寄存器壓力。(如果你常profile GEMM應該能有所體會)

a30b3ee6-aa37-11ee-8b88-92fbcf53809c.png

并且它是一種異步操作,意味著我們可以提前發(fā)射出好幾輪(在cutlass里往往稱為Stage)數(shù)據(jù)預取的指令,以實現(xiàn)延遲隱藏(我搬我的,你算你的)。

而另外一個比較特殊的指令則是LDMatrix,這個指令是用在SharedMemory到Register的過程。

為了盡可能打滿帶寬,在GlobalMemory->SharedMemory這一環(huán)節(jié)中,每個線程都是以128bit的訪問粒度去存儲。而前面也提到TensorCore對應每個線程對數(shù)據(jù)有不同的索引這也就導致每個線程需要的元素在SharedMemory上是不連續(xù)的。

a3313254-aa37-11ee-8b88-92fbcf53809c.png

以Slides為例,我們看T0線程,它需要T0,T8,T16,T24對應SharedMemory的第一個元素。在沒有LDMatrix之前,它需要對應四次LDS32操作,而如果我們調(diào)用LDMatrix,可以一個指令就完成上述的操作:

a34f32d6-aa37-11ee-8b88-92fbcf53809c.png

下面我們簡單提一下Cutlass的crosswise Layout(我看的不是很明白)。通常來說為了避免BankConflict,我們常見的做法是Padding多一個元素,讓Warp內(nèi)線程訪問錯開,但是這樣肯定是帶來了SharedMemory浪費。而Cutlass提出了一種新的Layout,通過一系列很復雜的異或操作算出來了一個索引,最終大概長這樣:

a364fda0-aa37-11ee-8b88-92fbcf53809c.png

這里每個線程存了128bit數(shù)據(jù),也就是占了4個bank。還是以剛剛線程0所需的數(shù)據(jù)為例,可以看到T0 T8 T16 T24都是錯開到不同的Bank上(其他線程同理)

下面是一個LDMatrix的example

PS:我不知道我寫的對不對,至少從結(jié)果上看還挺合理,如果有錯也麻煩指正

LDMatrix example

#include"stdio.h"
#include"stdint.h"
#include"cuda_fp16.h"

#defineLDMATRIX_X4(R0,R1,R2,R3,addr)
asmvolatile("ldmatrix.sync.aligned.x4.m8n8.shared.b16{%0,%1,%2,%3},[%4];
"
:"=r"(R0),"=r"(R1),"=r"(R2),"=r"(R3)
:"r"(addr))


template
__global__voidset_value(T*x,int32_telem_cnt){
for(inti=0;i(i%8);
}
}

//從CUTLASS里抄的
__device__uint32_tcast_smem_ptr_to_uint(voidconst*constptr){
//WeprefertousethenewCVTAintrinsicsiftheyareavailable,otherwisewewillfallbackto
//thepreviousinternalintrinsicsiftheyareavailable.
#ifCUTE_CVTA_GENERIC_TO_SHARED_ACTIVATED
//
//ThisNVVMintrinsicconvertsanaddressinsharedmemorytoaplain
//unsignedinteger.Thisisnecessarytopasstosharedmemoryinstructions
//ininlinePTX.
//
//InCUDA11andbeyond,thisreplaces__nvvm_get_smem_pointer()[onlyavailablein10.2].
//
//__device__size_t__cvta_generic_to_shared(void*ptr);

///CUTEhelpertogetSMEMpointer
returnstatic_cast(__cvta_generic_to_shared(ptr));

#elifCUTE_NVVM_GET_SMEM_POINTER_ACTIVATED

return__nvvm_get_smem_pointer(ptr);

#elifdefined(__CUDA_ARCH__)

uint32_tsmem_ptr;

asm(
"{.reg.u64smem_ptr;cvta.to.shared.u64smem_ptr,%1;cvt.u32.u64%0,smem_ptr;}
"
:"=r"(smem_ptr):"l"(ptr));

returnsmem_ptr;

#else


(void)ptr;
printf("ERROR:cast_smem_ptr_to_uintnotsupportedbutused.
");
return0;

#endif
}

__global__voidldmatrix_example(uint32_t*x,
uint32_t*y){
constint32_trow_tid=threadIdx.x/8;
constint32_tcol_tid=threadIdx.x%8;
uint32_tRegisterLoad[4];
uint32_tRegisterTensorcore[4];
__shared__halfsmem[4][64];
*reinterpret_cast(RegisterLoad)=*reinterpret_cast((x+threadIdx.x*4));

half*half_register_load_ptr=reinterpret_cast(RegisterLoad);
if(threadIdx.x==0){
printf("ThreadIdx:%d,Valueis:%f,%f,%f,%f,%f,%f,%f,%f.
",threadIdx.x,
static_cast(half_register_load_ptr[0]),static_cast(half_register_load_ptr[1]),
static_cast(half_register_load_ptr[2]),static_cast(half_register_load_ptr[3]),
static_cast(half_register_load_ptr[4]),static_cast(half_register_load_ptr[5]),
static_cast(half_register_load_ptr[6]),static_cast(half_register_load_ptr[7]));
}

int32_txor_idx=threadIdx.x;
if(row_tid==1){
xor_idx^=1;
}

if(row_tid==2){
xor_idx^=2;
}

if(row_tid==3){
xor_idx^=3;
}

constint32_tstore_smem_row_tid=xor_idx/8;
constint32_tstore_smem_col_tid=xor_idx%8;

//if(threadIdx.x==0){
printf("ThreadIdx:%d,XorIdxis:%d,store_smem_row_tidis:%d,store_smem_col_tidis:%d.
",threadIdx.x,xor_idx,store_smem_row_tid,store_smem_col_tid*8);
//}

half*smem_ptr=&(smem[store_smem_row_tid][store_smem_col_tid*8]);//smem[store_smem_row_tid][store_smem_col_tid*4];

*reinterpret_cast(smem_ptr)=*reinterpret_cast(RegisterLoad);

__syncthreads();

if(threadIdx.x==0||threadIdx.x==8||threadIdx.x==16||threadIdx.x==24){
printf("ThreadIdx:%d,SMEMValueis:%f,%f,%f,%f,%f,%f,%f,%f.
",threadIdx.x,
static_cast(smem[0][0]),static_cast(smem[0][1]),
static_cast(smem[0][2]),static_cast(smem[0][3]),
static_cast(smem[0][4]),static_cast(smem[0][5]),
static_cast(smem[0][6]),static_cast(smem[0][7]));
}

uint32_taddr=cast_smem_ptr_to_uint(smem_ptr);
LDMATRIX_X4(RegisterTensorcore[0],RegisterTensorcore[1],RegisterTensorcore[2],RegisterTensorcore[3],addr);

half*half_register_tensorcore_ptr=reinterpret_cast(RegisterTensorcore);

if(threadIdx.x==0){
printf("AfterLDMATRIX,ThreadIdx:%d,Valueis:%f,%f,%f,%f,%f,%f,%f,%f.
",
threadIdx.x,
static_cast(half_register_tensorcore_ptr[0]),static_cast(half_register_tensorcore_ptr[1]),
static_cast(half_register_tensorcore_ptr[2]),static_cast(half_register_tensorcore_ptr[3]),
static_cast(half_register_tensorcore_ptr[4]),static_cast(half_register_tensorcore_ptr[5]),
static_cast(half_register_tensorcore_ptr[6]),static_cast(half_register_tensorcore_ptr[7]));
}

}

__global__voidprintMatrix(half*result,constintm,constintn){
for(introw=0;row(result[row*n+col]));
}
printf("
");
}
}

intmain(){
half*x;
half*y;

constint32_tm=16;
constint32_tk=16;
constint32_tn=8;

cudaMalloc(&x,m*k*sizeof(half));
cudaMalloc(&y,m*k*sizeof(half));

set_value<<<1,?1>>>(x,m*k);
cudaMemset(y,0,sizeof(half)*m*k);

ldmatrix_example<<<1,?32>>>(reinterpret_cast(x),
reinterpret_cast(y));

//printMatrix<<<1,?1>>>(y,m,k);
cudaDeviceSynchronize();
cudaFree(x);
cudaFree(y);
}

對于 cast_smem_ptr_to_uint 這個函數(shù)我也不是很清楚,我從元戎啟行的矩陣轉(zhuǎn)置Blog里摘了一段:

需要額外注意的是,共享內(nèi)存的地址并不是全局同步地址(GenericAddress),因此在使用共享內(nèi)存地址讀取或?qū)懭霐?shù)據(jù)前,要經(jīng)過一次內(nèi)置函數(shù)__cvta_generic_to_shared,當然也可以自己手寫PTX

xor 換算索引 example

foriinrange(8,16):
print(i,i^1)

foriinrange(16,24):
print(i,i^2)

foriinrange(24,32):
print(i,i^3)s
    審核編輯:黃飛

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 寄存器
    +關(guān)注

    關(guān)注

    31

    文章

    5295

    瀏覽量

    119824
  • 數(shù)據(jù)類型
    +關(guān)注

    關(guān)注

    0

    文章

    236

    瀏覽量

    13596
  • 線程
    +關(guān)注

    關(guān)注

    0

    文章

    504

    瀏覽量

    19636
  • Warp
    +關(guān)注

    關(guān)注

    0

    文章

    8

    瀏覽量

    9574

原文標題:亂談CUTLASS GTC2020 SLIDES

文章出處:【微信號:GiantPandaCV,微信公眾號:GiantPandaCV】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    KITA2GTC3325VTRBSTOBO1開發(fā)板運行的是什么系統(tǒng)?

    請告知KITA2GTC3325VTRBSTOBO1 開發(fā)板運行的是什么系統(tǒng)(RTOS 或·····)?開發(fā)板的整個Demo code從哪里可以得到?
    發(fā)表于 02-01 06:10

    【限時領(lǐng)取精美禮品】報名2022 GTC大會,與行業(yè)大咖探索 AI 前沿科技

    NVIDIA GTC22 將于 3 月 21 日至 24 日線上舉辦。NVIDIA 創(chuàng)始人兼首席執(zhí)行官黃仁勛將帶來囊括眾多新聞發(fā)布的主題演講。電子發(fā)燒友平臺作為NVIDIA 初創(chuàng)加速計劃的生態(tài)伙伴
    發(fā)表于 03-18 11:06

    【中獎公示】恭喜在GTC22直播間中獎幸運鵝~快來登記領(lǐng)獎吧~

    請以下用戶盡快填寫兌獎信息,我們將在7個工作日內(nèi)發(fā)出獎品,感謝參與~戳這里>>GTC2022直播兌獎處
    發(fā)表于 03-23 14:12

    NVIDIA安培GPU或在明年3月底的GTC2020大會上推出

    從16nm Pascal到12nm Turing,NVIDIA最近兩代的GPU一直停留在16/12nm節(jié)點上,對最新的7nm工藝似乎沒啥興趣,反正友商從14nm到7nm工藝的顯卡都打不過NVIDIA顯卡,老黃確實不著急。
    發(fā)表于 11-09 10:06 ?2535次閱讀

    NVIDIA GTC或公布新一代Ampere安培架構(gòu)的GPU 將基于臺積電7nm工藝

    2020年的NVIDIA GTC大會將在3月22到26日舉行,屆時NVIDIA發(fā)布新一代Ampere安培架構(gòu)的GPU應該沒跑了,要知道GTC大會上已經(jīng)有兩三年沒發(fā)布真正的新一代GPU了,等的黃花菜都涼了。
    的頭像 發(fā)表于 01-04 10:13 ?3099次閱讀

    英偉達將在GTC 2020至少展示6款機器人

    除了顯卡之外,老黃近幾年也越來越關(guān)注AI與機器人,在下月舉行的GTC 2020上,英偉達宣布將至少展示6款機器人,它們高矮胖瘦各不同,具備不同的功能。
    的頭像 發(fā)表于 02-25 11:50 ?2259次閱讀

    NVIDIA GTC 2020大會如期舉行 官方表示將對場館進行全面消毒

    最近由于疫情的影響,一些大型展會、會議都在取消或者推遲,最嚴重的當然是MWC 2020展會取消。3月底還有NVIDIA的GTC大會,不過官方表示還在路上。
    的頭像 發(fā)表于 03-03 09:06 ?1451次閱讀

    NVIDIA取消GTC發(fā)布會,下一代安培跳票了

    全球蔓延的新冠疫情打亂了各種日常節(jié)奏,大量的發(fā)布會紛紛延期或取消。NVIDIA GTC 2020圖形開發(fā)者大會更是一波三折、命運多舛。
    的頭像 發(fā)表于 03-17 08:38 ?2414次閱讀

    NVIDIA宣布暫時停止分享GTC 2020的相關(guān)新聞 下一代“安培”核心正式跳票

    全球蔓延的新冠疫情打亂了各種日常節(jié)奏,大量的發(fā)布會紛紛延期或取消。NVIDIA GTC 2020圖形開發(fā)者大會更是一波三折、命運多舛。
    的頭像 發(fā)表于 03-17 08:55 ?2111次閱讀

    使用CUTLASS實現(xiàn)高性能矩陣乘法

      CUTLASS 實現(xiàn)了高性能卷積(隱式 GEMM )。隱式 GEMM 是作為 GEMM 的卷積運算的公式。這允許 Cutslass 通過重用高度優(yōu)化的 warp-wide GEMM 組件和以下組件來構(gòu)建卷積。
    的頭像 發(fā)表于 04-15 10:03 ?2800次閱讀

    MAX25400GTC/V+ MAX25400GTC/V+ - (Maxim Integrated) - 專用 IC

    電子發(fā)燒友網(wǎng)為你提供()MAX25400GTC/V+相關(guān)產(chǎn)品參數(shù)、數(shù)據(jù)手冊,更有MAX25400GTC/V+的引腳圖、接線圖、封裝手冊、中文資料、英文資料,MAX25400GTC/V+真值表,MAX25400
    發(fā)表于 11-16 20:01
    MAX25400<b class='flag-5'>GTC</b>/V+ MAX25400<b class='flag-5'>GTC</b>/V+ - (Maxim Integrated) - 專用 IC

    GTC23 | GTC 大會今日開幕!主題演講將于明日全球首播!

    萬眾矚目的 GTC23 今日開幕 主題演講將于 3 月 21 日全球首播 GTC23 于 3 月 20 日至 23 日舉行,本屆大會將舉辦超過 650 場由技術(shù)、商業(yè)、學術(shù)和政府領(lǐng)域領(lǐng)導者主持的會議
    的頭像 發(fā)表于 03-21 14:10 ?446次閱讀

    GTC 2023:阿里巴巴CUTLASS優(yōu)化探索推薦系統(tǒng)中的應用

    以TensorFlow為backend ,算子數(shù)量多;此前,我們通過算子融合(類Faster Transformer),CUDA Graph等手段已經(jīng)取得了不錯的性能提升;利用CUTLASS進一步優(yōu)化Attention和MLP計算, 可進步提升資源利用率。
    的頭像 發(fā)表于 03-24 17:06 ?2187次閱讀
    <b class='flag-5'>GTC</b> 2023:阿里巴巴<b class='flag-5'>CUTLASS</b>優(yōu)化探索推薦系統(tǒng)中的應用

    MAX14839GTC+T - (Maxim Integrated) - 接口 - 傳感器和探測器接口

    電子發(fā)燒友網(wǎng)為你提供Maxim(Maxim)MAX14839GTC+T相關(guān)產(chǎn)品參數(shù)、數(shù)據(jù)手冊,更有MAX14839GTC+T的引腳圖、接線圖、封裝手冊、中文資料、英文資料,MAX14839GTC+T真值表,MAX14839
    發(fā)表于 07-05 18:52
    MAX14839<b class='flag-5'>GTC</b>+T - (Maxim Integrated) - 接口 - 傳感器和探測器接口

    詳解CUTLASS的工作原理

    嗨,我們要開始了。我叫馬修·尼斯利。我是NVIDIA的深度學習compiler PM,今天我將介紹一些針對NVIDIA Tensorcores的使用方法。首先我要講一下Cutlass。我會給你一些
    的頭像 發(fā)表于 12-26 09:49 ?1640次閱讀
    詳解<b class='flag-5'>CUTLASS</b>的工作原理