kernel.cl 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. typedef float2 complex_f;
  2. /*
  3. * Addition of two complex numbers:
  4. *
  5. * a + b = (Re(a) + Re(b)) + i(Im(a) + Im(b))
  6. */
  7. static complex_f add(complex_f a, complex_f b)
  8. {
  9. return (complex_f)(a.x + b.x, a.y + b.y);
  10. }
  11. /*
  12. * Negation of a complex numbers:
  13. *
  14. * -a = -(Re(a) - i(Im(a))
  15. */
  16. static complex_f neg(complex_f a)
  17. {
  18. return (complex_f)(-a.x, -a.y);
  19. }
  20. /*
  21. * Multiplication of two complex numbers:
  22. *
  23. * a * b =
  24. * ((Re(a) * Re(b)) - (Im(a) * Im(b)))
  25. * + ((Im(a) * Re(b)) + (Re(a) * Im(b)))i
  26. */
  27. static complex_f mul(complex_f a, complex_f b)
  28. {
  29. return (complex_f)(
  30. (a.x * b.x) - (a.y * b.y),
  31. (a.y * b.x) + (a.x * b.y));
  32. }
  33. /**
  34. * Absolute value of a complex number
  35. *
  36. * |a| = √(Re(a)^2 + Im(a)^2)
  37. */
  38. static float complex_abs(complex_f a)
  39. {
  40. return sqrt((a.x * a.x) + (a.y * a.y));
  41. }
  42. static complex_f cexp(float a) {
  43. return (complex_f)(cos(a), sin(a));
  44. }
  45. /*
  46. * Returns the nth number where a given digit
  47. * is cleared in the binary representation of the number
  48. */
  49. static uint nth_cleared(uint n, uint target)
  50. {
  51. uint mask = (1 << target) - 1;
  52. uint not_mask = ~mask;
  53. return (n & mask) | ((n & not_mask) << 1);
  54. }
  55. ///////////////////////////////////////////////
  56. // KERNELS
  57. ///////////////////////////////////////////////
  58. /*
  59. * Applies a single qubit gate to the register.
  60. * The gate matrix must be given in the form:
  61. *
  62. * A B
  63. * C D
  64. */
  65. __kernel void apply_gate(
  66. __global complex_f *amplitudes,
  67. uint target,
  68. complex_f A,
  69. complex_f B,
  70. complex_f C,
  71. complex_f D)
  72. {
  73. uint const global_id = get_global_id(0);
  74. uint const zero_state = nth_cleared(global_id, target);
  75. // uint const zero_state = state & (~(1 << target)); // Could just be state
  76. uint const one_state = zero_state | (1 << target);
  77. complex_f const zero_amp = amplitudes[zero_state];
  78. complex_f const one_amp = amplitudes[one_state];
  79. amplitudes[zero_state] = add(mul(A, zero_amp), mul(B, one_amp));
  80. amplitudes[one_state] = add(mul(D, one_amp), mul(C, zero_amp));
  81. }
  82. /*
  83. * Applies a controlled single qubit gate to the register.
  84. */
  85. __kernel void apply_controlled_gate(
  86. __global complex_f *amplitudes,
  87. uint control,
  88. uint target,
  89. complex_f A,
  90. complex_f B,
  91. complex_f C,
  92. complex_f D)
  93. {
  94. uint const global_id = get_global_id(0);
  95. uint const zero_state = nth_cleared(global_id, target);
  96. uint const one_state = zero_state | (1 << target); // Set the target bit
  97. uint const control_val_zero = (((1 << control) & zero_state) > 0) ? 1 : 0;
  98. uint const control_val_one = (((1 << control) & one_state) > 0) ? 1 : 0;
  99. complex_f const zero_amp = amplitudes[zero_state];
  100. complex_f const one_amp = amplitudes[one_state];
  101. if (control_val_zero == 1)
  102. {
  103. amplitudes[zero_state] = add(mul(A, zero_amp), mul(B, one_amp));
  104. }
  105. if (control_val_one == 1)
  106. {
  107. amplitudes[one_state] = add(mul(D, one_amp), mul(C, zero_amp));
  108. }
  109. }
  110. /*
  111. * Applies a controlled-controlled single qubit gate to the register.
  112. * NOT MIGRATED
  113. */
  114. __kernel void apply_controlled_controlled_gate(
  115. __global complex_f *const amplitudes,
  116. __global complex_f *amps,
  117. uint control1,
  118. uint control2,
  119. uint target,
  120. complex_f A,
  121. complex_f B,
  122. complex_f C,
  123. complex_f D)
  124. {
  125. uint const state = get_global_id(0);
  126. complex_f const amp = amplitudes[state];
  127. uint const zero_state = state & (~(1 << target));
  128. uint const one_state = state | (1 << target);
  129. uint const bit_val = (((1 << target) & state) > 0) ? 1 : 0;
  130. uint const control1_val = (((1 << control1) & state) > 0) ? 1 : 0;
  131. uint const control2_val = (((1 << control2) & state) > 0) ? 1 : 0;
  132. if (control1_val == 0 || control2_val == 0)
  133. {
  134. // Control is 0, don't apply gate
  135. amps[state] = amp;
  136. }
  137. else
  138. {
  139. // control is 1, apply gate.
  140. if (bit_val == 0)
  141. {
  142. // Bitval = 0
  143. amps[state] = add(mul(A, amp), mul(B, amplitudes[one_state]));
  144. }
  145. else
  146. {
  147. amps[state] = add(mul(D, amp), mul(C, amplitudes[zero_state]));
  148. }
  149. }
  150. }
  151. /*
  152. * Swaps the states of two qubits in the register
  153. * NOT MIGRATED
  154. */
  155. __kernel void swap(
  156. __global complex_f *const amplitudes,
  157. __global complex_f *amps,
  158. uint first_qubit,
  159. uint second_qubit)
  160. {
  161. uint const state = get_global_id(0);
  162. uint const first_bit_mask = 1 << first_qubit;
  163. uint const second_bit_mask = 1 << second_qubit;
  164. uint const new_second_bit = ((state & first_bit_mask) >> first_qubit) << second_qubit;
  165. uint const new_first_bit = ((state & second_bit_mask) >> second_qubit) << first_qubit;
  166. uint const new_state = (state & !first_bit_mask & !second_bit_mask) | new_first_bit | new_second_bit;
  167. amps[new_state] = amplitudes[state];
  168. }
  169. /**
  170. * Calculates The Probabilities Of A State Vector
  171. */
  172. __kernel void calculate_probabilities(
  173. __global complex_f *const amplitudes,
  174. __global float *probabilities)
  175. {
  176. uint const state = get_global_id(0);
  177. complex_f amp = amplitudes[state];
  178. probabilities[state] = complex_abs(mul(amp, amp));
  179. }
  180. /**
  181. * Initializes a register to the value 1|0..100...0>
  182. * ^ target
  183. */
  184. __kernel void initialize_register(
  185. __global complex_f *amplitudes,
  186. uint const target)
  187. {
  188. uint const state = get_global_id(0);
  189. if (state == target)
  190. {
  191. amplitudes[state] = (complex_f)(1, 0);
  192. }
  193. else
  194. {
  195. amplitudes[state] = (complex_f)(0, 0);
  196. }
  197. }