GeNN  4.9.0
GPU enhanced Neuronal Networks (GeNN)
modularHost.c.h
Go to the documentation of this file.
1 
2  /*
3  ***********************************************************************
4  Copyright (c) 2015 Advanced Micro Devices, Inc.
5  All rights reserved.
6 
7  Redistribution and use in source and binary forms, with or without
8  modification, are permitted provided that the following conditions
9  are met:
10 
11  1. Redistributions of source code must retain the above copyright
12  notice, this list of conditions and the following disclaimer.
13 
14  2. Redistributions in binary form must reproduce the above copyright
15  notice, this list of conditions and the following disclaimer in the
16  documentation and/or other materials provided with the distribution.
17 
18  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 
30  ***********************************************************************
31  */
32 
33 #pragma once
34 #ifndef MODULAR_CH
35 #define MODULAR_CH
36 
54 // code that is common to host and device
56 
57 #ifdef MODULAR_FIXED_SIZE
58 # define N MODULAR_FIXED_SIZE
59 # define MATRIX_ELEM(mat, i, j) (mat[i][j])
60 #else
61 # define MATRIX_ELEM(mat, i, j) (mat[i * N + j])
62 #endif // MODULAR_FIXED_SIZE
63 
65 // @details Also works if A = C or B = C or A = B = C.
66 // @return C = A*B % m
67 #ifdef MODULAR_FIXED_SIZE
68 static void modMatMat (MODULAR_NUMBER_TYPE A[N][N], MODULAR_NUMBER_TYPE B[N][N], MODULAR_NUMBER_TYPE C[N][N], MODULAR_NUMBER_TYPE m)
69 #else
70 void modMatMat (size_t N, MODULAR_NUMBER_TYPE* A, MODULAR_NUMBER_TYPE* B, MODULAR_NUMBER_TYPE* C, MODULAR_NUMBER_TYPE m)
71 #endif
72 {
73  MODULAR_NUMBER_TYPE V[N];
74  MODULAR_NUMBER_TYPE W[N][N];
75  for (size_t i = 0; i < N; ++i) {
76  for (size_t j = 0; j < N; ++j)
77  V[j] = MATRIX_ELEM(B,j,i);
78 #ifdef MODULAR_FIXED_SIZE
79  modMatVec (A, V, V, m);
80 #else
81  modMatVec (N, A, V, V, m);
82 #endif
83  for (size_t j = 0; j < N; ++j)
84  W[j][i] = V[j];
85  }
86  for (size_t i = 0; i < N; ++i) {
87  for (size_t j = 0; j < N; ++j)
88  MATRIX_ELEM(C,i,j) = W[i][j];
89  }
90 }
91 
92 
94 // @details Also works if A = B.
95 #ifdef MODULAR_FIXED_SIZE
96 static void modMatPowLog2 (MODULAR_NUMBER_TYPE A[N][N], MODULAR_NUMBER_TYPE B[N][N], MODULAR_NUMBER_TYPE m, cl_uint e)
97 #else
98 void modMatPowLog2 (size_t N, MODULAR_NUMBER_TYPE* A, MODULAR_NUMBER_TYPE* B, MODULAR_NUMBER_TYPE m, cl_uint e)
99 #endif
100 {
101  // initialize: B = A
102  if (A != B) {
103  for (size_t i = 0; i < N; i++) {
104  for (size_t j = 0; j < N; ++j)
105  MATRIX_ELEM(B,i,j) = MATRIX_ELEM(A,i,j);
106  }
107  }
108  // Compute B = A^{2^e}mod m
109  for (cl_uint i = 0; i < e; i++)
110 #ifdef MODULAR_FIXED_SIZE
111  modMatMat (B, B, B, m);
112 #else
113  modMatMat (N, B, B, B, m);
114 #endif
115 }
116 
117 
119 // @details Also works if A = B.
120 #ifdef MODULAR_FIXED_SIZE
121 static void modMatPow (MODULAR_NUMBER_TYPE A[N][N], MODULAR_NUMBER_TYPE B[N][N], MODULAR_NUMBER_TYPE m, cl_uint n)
122 #else
123 void modMatPow (size_t N, MODULAR_NUMBER_TYPE* A, MODULAR_NUMBER_TYPE* B, MODULAR_NUMBER_TYPE m, cl_uint n)
124 #endif
125 {
126  MODULAR_NUMBER_TYPE W[N][N];
127 
128  // initialize: W = A; B = I
129  for (size_t i = 0; i < N; i++) {
130  for (size_t j = 0; j < N; ++j) {
131  W[i][j] = MATRIX_ELEM(A,i,j);
132  MATRIX_ELEM(B,i,j) = 0;
133  }
134  }
135 
136  for (size_t j = 0; j < N; ++j)
137  MATRIX_ELEM(B,j,j) = 1;
138 
139  // Compute B = A^n % m using the binary decomposition of n
140  while (n > 0) {
141  if (n & 1) // if n is odd
142 #ifdef MODULAR_FIXED_SIZE
143  modMatMat (W, B, B, m);
144  modMatMat (W, W, W, m);
145 #else
146  modMatMat (N, &W[0][0], B, B, m);
147  modMatMat (N, &W[0][0], &W[0][0], &W[0][0], m);
148 #endif
149  n >>= 1;
150  }
151 }
152 
153 #undef MATRIX_ELEM
154 #undef N
155 
156 #endif // MODULAR_CH
void modMatPowLog2(size_t N, MODULAR_NUMBER_TYPE *A, MODULAR_NUMBER_TYPE *B, MODULAR_NUMBER_TYPE m, cl_uint e)
Compute matrix B = (A^(2^e) % m)
Definition: modularHost.c.h:98
void modMatVec(size_t N, MODULAR_NUMBER_TYPE *A, MODULAR_NUMBER_TYPE *s, MODULAR_NUMBER_TYPE *v, MODULAR_NUMBER_TYPE m)
Matrix-vector modular multiplication.
Definition: device/modular.c.h:81
void modMatPow(size_t N, MODULAR_NUMBER_TYPE *A, MODULAR_NUMBER_TYPE *B, MODULAR_NUMBER_TYPE m, cl_uint n)
Compute matrix B = A^n % m.
Definition: modularHost.c.h:123
#define MATRIX_ELEM(mat, i, j)
Definition: modularHost.c.h:61
void modMatMat(size_t N, MODULAR_NUMBER_TYPE *A, MODULAR_NUMBER_TYPE *B, MODULAR_NUMBER_TYPE *C, MODULAR_NUMBER_TYPE m)
Compute A*B % m.
Definition: modularHost.c.h:70
m
Definition: genn_model.py:117