2017-07-25 17 views
18

Próbuję użyć funkcji cuBLAS w pakiecie Numba firmy Anaconda i mam problem. Potrzebuję macierzy wejściowych, aby były w kolejności C. Dane wyjściowe mogą być w kolejności Fortran.Macierze inne niż kwadratowe C w cuBLAS (numba)

Mogę uruchomić przykładowy skrypt dostarczony z pakietem, here. Skrypt ma dwie funkcje: gemm_v1 i gemm_v2. W gemm_v1 użytkownik musi utworzyć macierze wejściowe w kolejności Fortran. W gemm_v2, mogą one zostać przekazane do implementacji GEMM i przeniesione na urządzenie. Mogę uzyskać te przykłady do pracy z macierzami kwadratowymi. Nie mogę jednak dowiedzieć się, jak uzyskać gemm_v2 do pracy z macierzami wejściowymi innych niż kwadratowe. Czy istnieje sposób pracy z macierzami wejściowymi C-order, które nie są kwadratowe?

Uwaga:
Idealnie oba matryce wejściowe i wyjściowe będzie pozostawać w urządzeniu po wywołaniu GEMM być stosowane w innych obliczeń (jest częścią metody iteracyjnej).

+0

w wezwaniu do blas, określasz gemm (transa, transb, m, n, k, alfa, A: r, B: r, beta, C: w); gdzie transa i transb są operacjami, które należy zastosować do macierzy. W przykładzie gemm_v1 jest to operacja tożsamości, w przykładzie gemm_v2 jest to transpozycja. Następnie podaj m, n i k. Są to # pola A (m), # kolumny rzędów A/# B (n) i kolumny B (k). Jeśli utrzymasz go w składni przykładu, określisz go jako macierz z kwadratem, więc to jest miejsce, w którym można to zmienić. Upewnij się, że kształt twoich matryc jest zgodny z deklaracją. – Uvar

Odpowiedz

3

Problem z tym przykładem polega na tym, że działa on tylko dla macierzy kwadratowych. Jeśli macierze nie są kwadratowe, nie można obliczyć wartości A^t*B^t z powodu wymiaru missmatch (zakładając, że wymiary były odpowiednie dla A*B).

Nie mam działającej instalacji cuBLAS pod ręką, więc to rodzaj strzału w ciemności, ale byłbym naprawdę zaskoczony, gdyby cuBLAS działałby inaczej niż zwykły BLAS. BLAS spodziewa się, że macierze będą w kolumnie największego rzędu (również w kolejności Fortran), ale mogą być również używane dla macierzy w rzędzie-wyższym rzędzie (zwanym również zamówieniem C).

Moim zdaniem, co może być całkowicie błędne, gemm_v2 nie jest zwykłym/najlepszym sposobem na poradzenie sobie z mnożeniem dwóch macierzy C-rzędowych, na przykład dlatego, że jeśli mnoży się dwie macierze rzędu C, to można również uzyskać C- uporządkuj matrycę jako odpowiedź.

Sztuką obliczyć iloczyn dwóch C-order-macierzy przy pomocy gemm będzie działać w następujący sposób:

Nawet jeśli jest to zapewne znana wam, chciałbym najpierw opracować na wiersz poważnych porządek (układ c-pamięci) i kolumna-główny-porządek (układ fortran-memory), aby rozwinąć moją odpowiedź.

Więc jeśli mamy 2x3 (tzn 2 rzędy i 3 kolumny) macierzy A i przechowywać go w jakiejś ciągłej pamięci otrzymujemy:

row-major-order(A) = A11, A12, A13, A21, A22, A23 
col-major-order(A) = A11, A21, A12, A22, A13, A33 

Oznacza to, że jeśli mamy ciągłą pamięć, co oznacza macierz w rzędzie-wyższym rzędzie, i interpretujcie to jak macierz w kolumnie-major-rozkazie dostaniemy zupełnie inną macierz!

Jednak jeśli spojrzymy na transponowana macierz A^t możemy łatwo zobaczyć:

row-major-order(A) = col-major-order(A^t) 
col-major-order(A) = row-major-order(A^t) 

Oznacza to, że jeśli chcielibyśmy uzyskać macierz C w row-major-order jako konsekwencji blas-procedura powinna zapisywać transponowaną matrycę C w kolumnie-głównym porządku (po tym wszystkim, czego nie możemy zmienić) do tej właśnie pamięci. Jednakże, C^t=(AB)^t=B^t*A^t i B^t an A^t są oryginalnymi macierzami ponownie zinterpretowanymi w kolumnie głównej.

Teraz A być n x k -Matrix i Bk x m -Matrix, wezwanie gemm rutyny powinna być następująca:

gemm('N', 'N', m, n, k, 1.0, B, m, A, k, 0.0, C, m) 

Uwaga:

  1. My nie Muszą przetransponować macierze A i B, ponieważ jest to obsługiwane przez ponowne interpretowanie C-order jako Fortran-order.
  2. Musimy zamienić miejsca macierzy A i B, aby uzyskać C^t w kolejności Fortran jako wynik.
  3. Wynikowa macierz C jest w porządku C (reinterpretując ją od Fortran-order do C-order pozbywamy się ^t).