2017年12月26日 星期二

Cuda 9.0 範例程式 使用 for 迴圈複製陣列

Cuda 9.0 範例程式 使用 for 迴圈複製陣列

現在9版的安裝 cuda 好像沒有什麼難度了,順對弄對先安裝好 VisualStudio 然後再安裝 cuda 就一路下一步一直按到底就好了。
然後開啟VC就有專案可以開啟了
範例程序有for迴圈可以參考,這裡我把它簡化了一下一些流程並加上時間監控
首先先是計時函式庫
/*****************************************************************
Name : Timer.hpp
Date : 2017/12/19
By   : CharlotteHonG
Final: 2017/12/26
*****************************************************************/
#pragma once
#include <iostream>
#include <string>
#include <ctime>

class Timer {
public:
    Timer(std::string name=""): name(name){
        startTime = clock();
    }
    operator double() {
        return time;
    }
public:
    void start() {
        startTime = clock();
        flag=0;
    }
    void end() {
        finalTime = clock();
        time = (double)(finalTime - startTime)/CLOCKS_PER_SEC;
    }
    void print(std::string name="") {
        if (flag==0) {
            flag = 1;
            end();
        }
        if(name=="") {
            name=this->name;
        }
        if(priSta) {
            std::cout << "#" << name << ", " << " time = " << time << "s" << std::endl;
        }
    }
private:
    std::string name;
    clock_t startTime;
    clock_t finalTime;
    double time;
    bool flag = 0;
public:
    bool priSta = 1;
};
再來是控管 cuda 記憶體的類別,他可以用來自動要求空間並複製進去以及在程序結束時自動解構,不需要再 free() cuda記憶體。
由於這個有寫樣板所以沒法簡單把實作拆開,建議就直接寫在cuh裡面省事吧~
/*****************************************************************
Name : cudaData.cuh
Date : 2017/12/19
By   : CharlotteHonG
Final: 2017/12/19
*****************************************************************/
// Cuda 記憶體自動管理程序
template <class T>
class CudaData {
public:
    CudaData(){}
    CudaData(size_t size){
        malloc(size);
    }
    CudaData(T* dataIn ,size_t size): len(size){
        memcpyInAuto(dataIn, size);
    }
    ~CudaData(){
        if(gpuData!=nullptr) {
            cudaFree(gpuData);
            gpuData = nullptr;
            len = 0;
        }
    }
public:
    void malloc(size_t size) {
        this->~CudaData();
        len = size;
        cudaMalloc((void**)&gpuData, size*sizeof(T));
    }
    void memcpyIn(T* dataIn ,size_t size) {
        if(size > len) {throw out_of_range("memcpyIn input size > curr size.");}
        cudaMemcpy(gpuData, dataIn, size*sizeof(T), cudaMemcpyHostToDevice);
    }
    void memcpyInAuto(T* dataIn ,size_t size) {
        malloc(size);
        memcpyIn(dataIn, size);
    }
    void memcpyOut(T* dataIn ,size_t size) {
        cudaMemcpy(dataIn, gpuData, size*sizeof(T), cudaMemcpyDeviceToHost);
    }
    void memset(int value, size_t size) {
        if(size>len) {
            throw out_of_range("memset input size > curr size.");
        }
        cudaMemset(gpuData, value, size*sizeof(T));
    }
    size_t size() {
        return this->len;
    }
public:
    operator T*() {
        return gpuData;
    }
private:
    T* gpuData;
    size_t len=0;
};

主程式

再來是主程式了,會用到上面兩個函式庫

#include "cuda_runtime.h"
#include "device_launch_parameters.h"

#include <iostream>
#include <vector>
using namespace std;

#include "timer.hpp"
#include "CudaData.cuh"

__global__ void cudacopy(float* b, float* a, int size){
    // 乾式寫法
    const int idx = blockIdx.x*blockDim.x + threadIdx.x;
    if(idx<size){
        b[idx]=a[idx];
    }
    // 迴圈寫法
    for(int i=threadIdx.x; i<size; i+=blockDim.x){
        b[i]=a[i];
    }
}
void cpucopoy(float* b, float* a, int size) {
    for(int i=0; i<size; ++i){
        b[i]=a[i];
    }
}
void testCuda(size_t size) {
    Timer T;

    // 配置主機記憶體
    vector<float> img_data(size), cpu_data(size), gpu_data(size);
    float* a = img_data.data(); // 原始資料
    float* b = cpu_data.data(); // CPU計算後資料
    float* c = gpu_data.data(); // GPU輸出回來資料
    // 設置初值
    float test_val=7;
    for(int i=0; i<size; i++){
        a[i]=test_val;
    }

    // 配置顯示記憶體, 載入資料.
    T.start();
    CudaData<float> gpuDataIn(a, size), gpuDataOut(size);
    gpuDataOut.memset(0, size);
    T.print("  Cuda Data malloc and copy");

    // 網格區塊設定. (與 kernel for 的次數有關)
    const size_t blkDim=16;
    int grid(size/blkDim+1);  // 網格要含蓋所有範圍, 所以除完要加 1.
    int block(blkDim);        // 區塊設定 16x16.

    // Cuda Kernel 執行運算
    T.start();
    cudacopy<<<grid,block>>>(gpuDataOut, gpuDataIn, size);
    T.print("  Cuda-copy");
    // 取出GPU資料
    gpuDataOut.memcpyOut(c, size);

    // CPU 執行運算
    T.start();
    cpucopoy(b, a, size);
    T.print("  Cpu-copy");

    // 測試
    bool f=0;
    for(size_t i = 0; i < size; i++) {
        if(c[i] != b[i]) {f=1;}
    }

    // 測試報告
    if(f==0) {
        cout << "test ok" << endl;
    } else {
        cout << "test Error" << endl;
    }
}

int main(){
    Timer T;
    testCuda(1000);
    T.print("ALL time.");
    return 0;
}

Visual Studio 更改預設 include目錄 不用每次重設

Visual Studio 更改預設 include目錄 不用每次重設

有額外掛其他函式庫的話每次要重建一個新專案,都要重來過更改每一個目錄檔案,這實在是很麻煩痾。
找了一些方法可以永久設置並且對於已經設置好的專案也有效果!
最底下有人懶人包一件安裝,只要把.h檔案放進去桌面產生的捷徑內就好。

設置目錄文件

VisualStudio預設讀取的檔案目錄
%USERPROFILE%\AppData\Local\Microsoft\MSBuild\v4.0
直接貼上就好不用自己改使用者名稱,進來之後可以看到有4個檔案
其中
  • Microsoft.Cpp.Win32.user.props
  • Microsoft.Cpp.x64.user.props
是我們要修改的檔案,就是選擇64位元跟32位元的時候不同的位置
先在這裡新建兩個資料夾分別是(之後做完在改你自己要的名字區分不同程式)
  • include
  • lib
接著先修改 Microsoft.Cpp.x64.user.props 這一份檔案,在 </Project> 前加入下面的字樣
  <!-- UserDfine -->
  <PropertyGroup>
  <IncludePath>$(UserRootDir)\include;$(IncludePath)</IncludePath>
  <LibraryPath>$(UserRootDir)\lib;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64</LibraryPath>
  </PropertyGroup>
修完之後差不多變成這個樣子
再來是 Microsoft.Cpp.x64.user.props 這一份檔案,就是把剛剛有x64的地方改成x86
  <!-- UserDfine -->
  <PropertyGroup>
  <IncludePath>$(UserRootDir)\include;$(IncludePath)</IncludePath>
  <LibraryPath>$(UserRootDir)\lib;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86</LibraryPath>
  </PropertyGroup>

放入文件

這邊用 gcc 的文件 bits/stdc++.h 做示範,文件可以從這裡下載
https://charlottehong.blogspot.tw/2017/06/visual-studio-2017.html
這個文件的功用是把 C++ 全部的函式庫都載入,這樣妳就不用擔心少載入什麼還要打了;當然這會有一些副作用,不過練習的時候可以少打確實有一些益處,實際開發的專案就不建議這麼做了。
把它丟進來吧

實測

再來需要重啟一下你的VisualStudio,如果你正開著的話。
測試一下開一個全新專案能不能直接引入(舊有已經建立的專案也有效)
/*****************************************************************
Name : 
Date : 2017/12/26
By   : CharlotteHonG
Final: 2017/12/26
*****************************************************************/
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
//================================================================
int main(int argc, char const *argv[]){
    vector<int> chg;
    return 0;
}
//================================================================
有的話就可以瞜~再來自己丟進去就好了
如果需要分類,比如說opencv你想額外建一個資料夾就修改文檔
$(UserRootDir)\include;$(IncludePath)
這裡的 $(UserRootDir) 就是底下這個位置
%USERPROFILE%\AppData\Local\Microsoft\MSBuild\v4.0
用分號隔開表示多個,有第三個就在加一個分號比如說加一個 opencvInc 資料夾
<IncludePath>$(UserRootDir)\opencvInc;$(UserRootDir)\include;$(IncludePath)</IncludePath>

一件安裝懶人包

https://goo.gl/aAHg62
安裝完畢桌面產生一個捷徑就是文中說明的位置,把檔案置放進去就好了。

參考

2017年12月25日 星期一

sublime text3 stino 編譯 arudino 上傳程式碼時錯誤

sublime text3 stino 編譯 arudino 上傳程式碼時錯誤

需要安裝一個套件 stiuno 安裝完畢就可以使用,之後再補詳細過程,今天解決了一個bug先放上來。

紀錄

之前編譯的時候就有遇到這個問題,明明都很正在用在編譯,可是編譯到一半突然就不能用了,重新開機重裝也是一樣,百思不解。
我有上作者的 github 上發問,也沒得到什麼解QuQ
https://github.com/Robot-Will/Stino/issues/436
後來有過了幾個月之後我又去試試看,莫名其妙就自己好了我就沒在管它了。今天在學校重新安裝了一台電腦,這台電腦有重灌過是乾淨的新系統。
沒想到居然彈出一樣的信息,google一下找到自己的文章…..沒有什麼比這個更絕望的你們知道嗎~嗚嗚。

解決辦法

錯誤信息
[Build] C:/Users/Charlotte/OneDrive/Git Repository/BT_ATC...
[Step 1] Check Toolchain.
[Error] Toolchain is not ready. Please build the sketch after the toolchain installation done.
後來我重新開啟 sublmie 他彈出一個視窗在中間上方,要我選擇 UTF8 還有另一個(有時候會彈出這樣的畫面,我也不是很明白是怎麼回事)。
然後我選擇UTF8之後就一切恢復正常了。
有可能是不支持某個格式,之前用 Arduino 編譯器存檔的直接用地三方文本編譯器開有中文會變成亂碼的經驗。
我再用sublimetext也有經驗是編輯到一半突然變成亂碼,不知道是不是我裝了套件影響的,估計是變成其他格式導致stino出問題。
那一篇發問的文章後面有人給出官方的文章
https://playground.arduino.cc/Code/UTF-8
我不確定直接轉是不是有用,你可以試試看,如果你沒有自動彈出。

2017年12月23日 星期六

google雲端硬碟 對資料夾 做副本,複製一份到自己的帳戶

google雲端硬碟 對資料夾 做副本,複製一份到自己的帳戶

對著資料夾建立

在FileURL貼上網址,然後下面選擇自己的雲端空間即可。
(下面中文是直接用google翻譯網頁的)
第一次要授權你的雲端帳號給他用
(建議有重要資料的帳號不要授權,權限開很大)
最後按保存它就會開始複製了
如果沒有複製完全部,可能是副本的容量太大了爆了。
Google雲端對於副本建立,會算入流量限制內,一個帳號一天最多能有100G~150G左右的流量的樣子(詳細多少我沒有去測試,只是依照經驗概算)。
  • 這個就跟分享檔案被太多人下載爆掉一樣,同一個流量。


如何撤銷應用程式的存取權限

進去之後把多餘不要的刪除即可。


第二種方式(舊文)

選擇建立副本
接下來有副本有兩個功能按鈕在上方
第一個是取得你空間的所有權,那個軟體可以自由存取你的雲端硬碟。(我自己也是有點怕怕的,會在意資料隱私或有重要資料夾建議換個帳號)
移除應用程式對帳戶存取權限可以參考下面的網址,如果同時登入多個帳號右上角選一下就可以了。
https://myaccount.google.com/u/0/permissions?pageId=none
接下來請複製你要的連結後面那一長串
貼入這個位置
按下剛剛第一張圖的選項2,就會自動建立整個資料夾副本進去了
不過實際使用上有容量限制,這個是google方的限制,建立副本每日只有100G的限額。

2017年12月21日 星期四

Visual Studio 2017 專案檔案越來越大 ipch 可以刪除嗎

Visual Studio 2017 專案檔案越來越大 ipch 可以刪除嗎

可以安新把他幹掉吧,事實上還有更多可以刪除,他的路徑在
\.vs\Sift\v15\ipch\AutoPCH
這個文件內的資料匣是一堆亂碼,可以直接全砍; .vs 這個資料夾刪除也可以直接刪除,下次打開會自動重建, 不過這會導致已經打開的頁面還有,頁面停留所位置等等的信息被刪除,如果要複製給別人直接刪除是個好做法。
其他可以刪除的文件可參考gitgub上的官方文件,文件裡面有提到的副檔名都是不重要可以看刪除的。

參考

I’m not only a C# moderator but also a C++ user :} The ipch directory and the many, many new files generated by the compiler can be safely deleted. In fact they should be deleted (and probably are) for clean builds. I teach a C++ college class myself and here is what I require my students to do.
In the solution folder delete all bin, obj, ipch, debug and release directories.
Delete any .suo files
Delete any .user files
Delete any .ncb files
Delete any .sbr files
Delete any .*log files (for VS 2010)
Zip up the entire solution directory for submission. This ensures that the solution and project structure remain intact.
PS I’ll move the post to the C++ forums.

Visual studio 如何自動開啟 錯誤清單

Visual studio 如何自動開啟 錯誤清單

最初一開始設定時候如果選擇 C++ 就不會自動開啟,選擇一般才會。後來才發現原來可以自己手動開啟,在選項裡面。
打勾就可以正常使用了

2017年12月12日 星期二

Visutal studio 2017 更新後 CUDA9.0 出錯 如何更正

Visutal studio 2017 更新後 CUDA9.0 出錯 如何更正

上次的更新拿掉了一些更新,這次的更新 CUDA9.0 也變得不支持了,而且沒辦法降低版本。解決辦法可以安裝先前的套件,他就會自動運行了。
錯誤訊息
unsupported Microsoft Visual Studio version! Only the versions 2012, 2013, 2015 and 2017 are supported!

Step1

開始搜尋 Visual Studio Installer 開啟安裝檔案程式,然後選擇修改
install this package
裝回來之後 VS2017 重啟之後就可以編過 cuda 測試的代碼了
then restart VS2017

Step2

改變方案版本

Select Visual Studio 2015

other

但是這還是有問題,我不知道為何改過之後他就不會自動重新編譯檔案了,即便我更改了代碼,解決辦法就是使用 Ctrl+F7 重新編譯所有檔案。
這個可能不是好辦法,專案如果很大不可能每次都重新編譯所有檔案,最好的辦法只能等待CUDA更新或是乾脆降板使用 VS2015,使用舊版的 VS2017。
But this have a problem.
VS can not rebuild file.
Even if change code.
Use Ctrl+F7 rebuild all file.
or reinstall old version visual studio.

參考 Referance