CUDA程式優化心得之錯誤處理
標準C提供了錯誤輸出函式perror,其功能是將在呼叫其處最近之前出錯的錯誤輸出到的標準錯誤流,當然利用作業系統的功能,你也可以將它們重定向到檔案。
由於CUDA函式設計為都返回錯誤碼,而且CUDA本身也提供了兩個函式cudaGetLastError和cudaGetErrorString,因此其處理可充分利用這兩個函式,另外我們在寫CUDA程式時,經常要驗證結果和CPU上的結果是否一致,因此我也提供了這個功能。
程式程式碼如下:
class ErrorHander{//file:file name;line:lineNo
const static float EPSFLOAT = 0.000001;
const static double EPSDOUBLE = 0.0000000001;
public :
#ifdef __CUDACC__
//can't use it at asynchronize situation
void static printError(cudaError_t cet){
if(cudaSuccess != cet){
printf("error:%s\n",cudaGetErrorString(cet));
fflush(stdout);
exit(1);
}
}
//can use it at anywhere
void static printLastError(){
cudaThreadSynchronize();
cudaError_t cet = cudaGetLastError();
if(cudaSuccess != cet){
printf("error:%s!\n",cudaGetErrorString(cet));
fflush(stdout);
exit(1);
}
}
void static printError(int line,cudaError_t cet){
if(cudaSuccess !=cet){
printf("line:%d,error:%s\n",line,cudaGetErrorString(cet));
fflush(stdout);
exit(1);
}
}
void static printLastError(int line){
cudaThreadSynchronize();
cudaError_t cet = cudaGetLastError();
if(cudaSuccess != cet){
printf("line:%d,error:%s!\n",line,cudaGetErrorString(cet));
fflush(stdout);
exit(1);
}
}
void static printError(char *file,int line,cudaError_t cet){
if(cudaSuccess != cet){
printf("%s,line:%d,error:%s\n",file,line,cudaGetErrorString(cet));
fflush(stdout);
exit(1);
}
}
void static printLastError(char *file,int line){
cudaThreadSynchronize();
cudaError_t cet = cudaGetLastError();
if(cudaSuccess != cet){
printf("%s,line:%d,error:%s!\n",file,line,cudaGetErrorString(cet));
fflush(stdout);
exit(1);
}
}
#endif
void static valid(const int *first,const int *second, int num, int firstSpan = 1,
int secondSpan = 1, int firstOffset = 0, int secondOffset = 0){
for(int i=0;i
assert(first[firstOffset+i*firstSpan]==second[secondOffset+i*secondSpan]);
}
}
void static valid(const float *first, const float *second, int num, int firstSpan = 1,
int secondSpan = 1, int firstOffset = 0, int secondOffset = 0){
for(int i=0;i
assert(abs(1-(first[firstOffset +
i*firstSpan]/second[secondOffset+i*secondSpan]))
}
}
void static valid(const double *first, const double *second, int num, int firstSpan = 1,
int secondSpan = 1, int firstOffset = 0, int secondOffset = 0){
for(int i=0;i
assert(abs(1-(first[firstOffset +
i*firstSpan]/second[secondOffset+i*secondSpan]))
}
}
};
printError函式列印傳入的cuda函式返回的錯誤碼所代表的錯誤,printLastError列印最後一次錯誤的錯誤字串。file代表檔名,呼叫時可用__FILE__巨集代替,line代表行數,呼叫時可傳入__LINE__巨集,當然由於設計上的缺陷,你也可以傳入其它的資訊。valid函式用於確定兩個陣列的資料是不是一樣的,本來想使用模板,但是還是使用了過載。由於全部採用靜態函式,所以我們沒有必要建立物件,直接使用類名呼叫就行了,這樣可以方便的使用條件編譯來啟用/關閉除錯資訊,這一點比cutil庫的cudaSafeCall好用得多。另外這個類的功能也足夠使用了。如果你想改變精度限的話,改變EPS變數的值就可以了。非常的方便。
另,由於能力所限或者說設計缺陷,printError各函式都無法處理非同步呼叫錯誤。另外這些工具函式只是拿來除錯用的,真正的出錯處理不能這樣做。
當然我個人的庫包含的類遠比這要多,比如還有檔案輸入輸出,隨機數初始化等。這些內部就不包括在本節了。
整體而言,這兩節都是一些準備工作。從下一節起才真正涉及到優化的內容。
由於CUDA函式設計為都返回錯誤碼,而且CUDA本身也提供了兩個函式cudaGetLastError和cudaGetErrorString,因此其處理可充分利用這兩個函式,另外我們在寫CUDA程式時,經常要驗證結果和CPU上的結果是否一致,因此我也提供了這個功能。
程式程式碼如下:
class ErrorHander{//file:file name;line:lineNo
const static float EPSFLOAT = 0.000001;
const static double EPSDOUBLE = 0.0000000001;
public :
#ifdef __CUDACC__
//can't use it at asynchronize situation
void static printError(cudaError_t cet){
if(cudaSuccess != cet){
printf("error:%s\n",cudaGetErrorString(cet));
fflush(stdout);
exit(1);
}
}
//can use it at anywhere
void static printLastError(){
cudaThreadSynchronize();
cudaError_t cet = cudaGetLastError();
if(cudaSuccess != cet){
printf("error:%s!\n",cudaGetErrorString(cet));
fflush(stdout);
exit(1);
}
}
void static printError(int line,cudaError_t cet){
if(cudaSuccess !=cet){
printf("line:%d,error:%s\n",line,cudaGetErrorString(cet));
fflush(stdout);
exit(1);
}
}
void static printLastError(int line){
cudaThreadSynchronize();
cudaError_t cet = cudaGetLastError();
if(cudaSuccess != cet){
printf("line:%d,error:%s!\n",line,cudaGetErrorString(cet));
fflush(stdout);
exit(1);
}
}
void static printError(char *file,int line,cudaError_t cet){
if(cudaSuccess != cet){
printf("%s,line:%d,error:%s\n",file,line,cudaGetErrorString(cet));
fflush(stdout);
exit(1);
}
}
void static printLastError(char *file,int line){
cudaThreadSynchronize();
cudaError_t cet = cudaGetLastError();
if(cudaSuccess != cet){
printf("%s,line:%d,error:%s!\n",file,line,cudaGetErrorString(cet));
fflush(stdout);
exit(1);
}
}
#endif
void static valid(const int *first,const int *second, int num, int firstSpan = 1,
int secondSpan = 1, int firstOffset = 0, int secondOffset = 0){
for(int i=0;i
}
}
void static valid(const float *first, const float *second, int num, int firstSpan = 1,
int secondSpan = 1, int firstOffset = 0, int secondOffset = 0){
for(int i=0;i
}
void static valid(const double *first, const double *second, int num, int firstSpan = 1,
int secondSpan = 1, int firstOffset = 0, int secondOffset = 0){
for(int i=0;i
}
};
printError函式列印傳入的cuda函式返回的錯誤碼所代表的錯誤,printLastError列印最後一次錯誤的錯誤字串。file代表檔名,呼叫時可用__FILE__巨集代替,line代表行數,呼叫時可傳入__LINE__巨集,當然由於設計上的缺陷,你也可以傳入其它的資訊。valid函式用於確定兩個陣列的資料是不是一樣的,本來想使用模板,但是還是使用了過載。由於全部採用靜態函式,所以我們沒有必要建立物件,直接使用類名呼叫就行了,這樣可以方便的使用條件編譯來啟用/關閉除錯資訊,這一點比cutil庫的cudaSafeCall好用得多。另外這個類的功能也足夠使用了。如果你想改變精度限的話,改變EPS變數的值就可以了。非常的方便。
另,由於能力所限或者說設計缺陷,printError各函式都無法處理非同步呼叫錯誤。另外這些工具函式只是拿來除錯用的,真正的出錯處理不能這樣做。
當然我個人的庫包含的類遠比這要多,比如還有檔案輸入輸出,隨機數初始化等。這些內部就不包括在本節了。
整體而言,這兩節都是一些準備工作。從下一節起才真正涉及到優化的內容。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/23057064/viewspace-662699/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Golang通脈之錯誤處理Golang
- 程式錯誤型別及其處理型別
- 錯誤處理
- 優化 Go 錯誤處理,魔改 Go recover 靠譜嗎?優化Go
- async/await 優雅的錯誤處理方法AI
- 開心檔之Go 錯誤處理Go
- Go 錯誤處理Go
- Python錯誤處理Python
- PHP 錯誤處理PHP
- php錯誤處理PHP
- 錯誤處理:如何通過 error、deferred、panic 等處理錯誤?Error
- 如何在 Go 中優雅的處理和返回錯誤(1)——函式內部的錯誤處理Go函式
- 二、GO 程式設計模式:錯誤處理Go程式設計設計模式
- openGauss 處理錯誤表
- go的錯誤處理Go
- axios 的錯誤處理iOS
- go-carbon 1.2.6 版本釋出,優化錯誤處理機制,棄用出錯直接panic的粗暴處理方式Go優化
- Yii2 之錯誤處理深入分析
- Python之錯誤異常和檔案處理Python
- 遠端連線錯誤程式碼及處理
- Python錯誤處理和異常處理(二)Python
- 如何優雅的在Golang中進行錯誤處理Golang
- grpc中的錯誤處理RPC
- laravel9 錯誤處理Laravel
- PHP 核心特性 - 錯誤處理PHP
- 15-錯誤處理(Error)Error
- Go語言之錯誤處理Go
- 學習Rust 錯誤處理Rust
- Oracle異常錯誤處理Oracle
- 淺談前端錯誤處理前端
- ORACLE 異常錯誤處理Oracle
- ogg複製程式報ORA-01438錯誤處理
- rust學習十、異常處理(錯誤處理)Rust
- 關於laravel的錯誤頁面處理大家都是如何優雅的處理的呢?Laravel
- 對比程式語言的四種錯誤處理方法,哪種才是最優方案?
- PHP安裝後錯誤處理PHP
- go 錯誤處理設計思考Go
- 常用模組 PHP 錯誤處理PHP
- Restful API 中的錯誤處理RESTAPI