2016年8月4日 星期四

Rails Debug ByeBug 使用筆記


在程式碼中想要中斷的地方加入 byebug,程式執行到 byebug 這個位置則會停下來讓使用者 debug


// 進入 byebug 頁面
[9, 18] in /Users/akiicat/someplace.rb
    9:     byebug
   10: 
   11:     @message.save!
   12: 
   13: 
=> 14:     @path = conversation_path(@conversation)
   15:   end
   16: 
   17:   private
   18: 
(byebug) d @path


指令說明
  • list: 
    列出程式碼 縮寫為
     l 
    ,
     l- 
    ,
     l= 
  • cont: 
    退出 byebug 讓程式執行完
  • quit: 
    退出 byebug 且結束
  • next: 
    執行到下一個段落 end 縮寫
     n 
  • step: 
    執行下一行 縮寫
     s 
  • display [參數]: 
    印出參數的值 縮寫
     disp 

2016年8月3日 星期三

Javascript try catch throw



  • try 如過錯誤會在 catch 接住把錯誤印出來,而 final 不管有沒有錯誤都會執行

try {
    ...
} 
catch(e) {
    console.log(e);
}
final {
    ...
} 


  • nest try catch throw 則會把錯誤丟到外層

try {
    ...
    try {
        ...
    }
        catch(e) {
        console.log(e);
        throw(e);       // 把錯誤丟到外層
    }  
} 
catch(e) {
    console.log(e);
} 
final {
    ...
}

2015年4月19日 星期日

AkiiNote PHP HTML 多個按鈕

PHP with HTML
Multiple Buttons on a Form

from:http://stackoverflow.com/a/4120694/4777620

先做兩個按鈕
method 可以改成用get 來看看是不是正確
<form action='' method='post'>
  <button type='submit' name='reset'>Clear</button>
  <button type='submit' name='submit'>Submit</button>
</form>

PHP 提交之後
可以用以下的方法來接住
if(isset($_POST['reset'])) { /* ...clear and reset stuff... */ }
else if(isset($_POST['submit']) { /* ...submit stuff... */ }

以下是另一種方法
<form action='' method='post'>
  <button name='submit' value='0'>Clear</button>
  <button name='submit' value='1'>Submit</button>
  <button name='submit' value='2'>Something Else</button>
</form>

PHP 提交之後
if($_POST['submit']==0)      { /* ...clear and reset stuff... */ }
else if($_POST['submit']==1) { /* ...submit stuff... */ }
else if($_POST['submit']==2) { /* ...do something else... */ }

2014年12月8日 星期一

AkiiNote CUDA 筆記

CUDA

CUDA的寫法大概就像下面那樣 幾乎每個CUDA都很類似:

開一個足夠大的空間然後給初始值 -> 複製記憶體到GPU -> 呼叫kernel function執行GPU -> 把最後的結果複製回來

在寫CUDA的程式 最需要注意的部分:

l   GPU的記憶體不大(1G2G……)

在資料很龐大的時候
就必須要想怎麼樣才能把資料縮小
所以在資料的處理上要費不少心思


如果需要用到二維的話 建議使用一維的方式來表達y*N+x
(個人認為在呼叫一維的kernel比較簡單

廢話講完了
以下是矩陣相加的例子:
C = A + B

在global 的地方宣告變數
初始值先給NULL 待會再用malloc 動態宣告記憶體
int* h_A = NULL;    // host
int* h_B = NULL;
int* h_C = NULL;
int* d_A = NULL;    // device
int* d_B = NULL;
int* d_C = NULL;
int N = 10


一開始讀取指令的值
N 是矩陣的邊長
size 是先計算需要開多大的空間來存放這些值
  assert(argc == 2); 
  N = atoi(argv[1]); 
  int size = N*N*sizeof(int);
  printf("N:%d, size:%d\n", N, size);
   
然後用malloc 開記憶體的空間
以下是host 的A B C
  h_A = (int*)malloc(size); 
  h_B = (int*)malloc(size); 
  h_C = (int*)malloc(size);
  assert(h_A); 
  assert(h_B); 
  assert(h_C); 
 
  // initial array A & B
在來就是初始h_A 和h_B 的值

 在來是宣告cuda 記憶體的空間,因為要用GPU作計算前,必須先把記憶體上的h_A跟h_B複製到GPU上的記憶體
  cudaMalloc((void**)&d_A, size);
  cudaMalloc((void**)&d_B, size);
  cudaMalloc((void**)&d_C, size);
  printf("d_A: %p\n", d_A);
  printf("d_B: %p\n", d_B);
  printf("d_C: %p\n", d_C);

然後
把h_A複製到GPU上的d_A
把h_B複製到GPU上的d_B
  cudaMemcpy(d_A, h_A, size, cudaMemcpyHostToDevice);
  cudaMemcpy(d_B, h_B, size, cudaMemcpyHostToDevice);

接下來就可以執行囉
這邊就是設定
每個Grid 有幾個Blocks
每個Block 有幾個threads
一個thread 就能執行矩陣上的一個點
  int threadsPerBlock = 256;
  int blocksPerGrid = (N + threadsPerBlock - 1) / threadsPerBlock;

然後在呼叫Kernel function 就可以執行囉
後面括弧的地方是參數值(這個應該沒問題啦)
  kernel<<<blocksPerGrid, threadsPerBlock>>>(d_A, d_B, d_C, N);

 最後由GPU執行完,在把加過的值複製回到local memory
  cudaMemcpy(h_C, d_C, size, cudaMemcpyDeviceToHost);


以下這個部分沒有算好的話 可是非常容易爆掉的

threadsPerBlock:每個block有幾個threads。這個就要看你到底是什麼的GPU了,如果會爆掉的話就改小一點吧。

blocksPerGrid:每個grid有幾個block。如果原本需要執行N次,那現在就只需要執行(N + threadsPerBlock - 1) / threadsPerBlock次。

在GPU 裡面
kernel在執行的時候盡量讓資料獨立

而且在GPU做運算得時候
呼叫kernel function上面的參數都是屬於GPU global值
像是以下程式碼的A B 或 C 
(N 也算啦 可是值有一個值 比較不會影響)

所以要加快運算的話可以先把
global 的資料複製到local來執行
執行完後再存回global 減少跟global存取的次數 
比較複雜的kernel function 能加快不少的時間
(矩陣相加不明顯)

__global__ void kernel(int* A, int* B, int* C, int N) {
  int n = blockIdx.x * blockDim.x + threadIdx.x;

// 這邊使用if 是用來判斷n 是不是在矩陣的範圍內
  if ( n < N){
    int local_a = A[n];
    int local_b = A[n];
    // exec……
    C[n] = local_a + local_b;
 }
}

最後執行完後
別忘了把記憶體給釋放掉喔

cudaFree(d_A);
cudaFree(d_B);
cudaFree(d_C);
free(h_A);
free(h_B);

free(h_C);

2014年10月23日 星期四

AkiiNote Pthread 筆記

Hmmmmmm要從哪開始講起呢






既然是pthread的模板 就又從pthread的模板講起
下面的codepthread模板
大部分簡單的平行化都可以解決 小細節的話再從模板中慢慢加進去

#include <assert.h>
#include <pthread.h>

pthread_t *thread_array = NULL;

int main(){
               thread_array = (pthread_t*) malloc(sizeof(pthread_t) * thread_num);
               for (i = 0; i < thread_num; ++i) {
                               int rc = pthread_create(thread_array+i, &attr, analyzer, (void *) i);
                               assert(rc == 0);
               }
               for (I = 0; I < thread_num; ++i) {
                               pthread_join(thread_array[i], NULL);
               }
               return 0;
}





動態(dynamic)宣告pthread個數
  •  thread_array1static參數 需要事先給值
  •  thread_array2dynamic參數 可以等程式執行到之後再給值

// thread_array1

pthread_t thread_array1[thread_num];
// thread_array2
pthread_t *thread_array2 = NULL;
thread_array2 =  (pthread_t*) malloc(sizeof(pthread_t) * thread_num);
// 開始平行化
pthread_create(thread_array+i, … );
pthread_join(thread_array[i], … );

pthread_create()簡單來說就是create thread
用來跟電腦講說 哪個function需要平行化
int pthread_create(pthread_t *thread,                           
                               const pthread_attr_t *attr,
                               void *(*start_routine) (void *),
                               void *arg);

第一個參數:可以用來設定平行化的維度 簡單來說就是設定同一時間可以有幾個thread在執行
第二個參數:用來設定平行化後分支出去的thread是否要回到main中 等等會講
第三個參數:需要平行化的function
第四個參數:傳遞參數 沒有參數則寫NULL

pthread_join()簡單來說就是join thread
跟電腦講說 分支出去後的thread要在哪裡回來(像是回到main)

int pthread_join(pthread_t thread, void **retval);

第一個參數:要join第幾個thread回來
第二個參數:thread function回傳值


attr
attr 屬性 有兩種
  •  joinable thread:需要呼叫pthread_join()才會停止
  •  detached thread:在thread function中加上pthread_exit()就會結束並釋放資源

畫個圖就淺顯易懂了


pthread_attr_t attr;

pthread_attr_init(&attr);  
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_create(&thread1, &attr, function, arg);
pthread_attr_destroy(&attr);




Mutex

再來就是mutex
加在mutex中間的code會逐一直行
不會同時並行

pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_lock(&mutex1);
/*---------*/
pthread_mutex_unlock(&mutex1);

pthread_mutex_init(&mutex2, NULL);
pthread_mutex_destroy(&mutex2, NULL);


Semaphore 跟mutex很像
但是我還是不太清楚semaphore應該應用在什麼地方上

pthread portal