Recovered source transcript
1/**
2 * simd_substrate.hpp - SIMD-Optimized Consciousness Substrate
3 *
4 * High-performance implementation using:
5 * - SSE/AVX intrinsics for x86
6 * - NEON intrinsics for ARM
7 * - Fallback scalar implementation
8 *
9 * Achieves ~4-8x speedup for substrate operations.
10 */
11
12#ifndef SIMD_SUBSTRATE_HPP
13#define SIMD_SUBSTRATE_HPP
14
15#include <cstdint>
16#include <cstddef>
17#include <cmath>
18#include <cstring>
19#include <array>
20#include <algorithm>
21#include "consciousness_api.hpp"
22
23// Detect SIMD support
24#if defined(__AVX512F__)
25 #define SIMD_AVX512 1
26 #include <immintrin.h>
27#elif defined(__AVX2__)
28 #define SIMD_AVX2 1
29 #include <immintrin.h>
30#elif defined(__AVX__)
31 #define SIMD_AVX 1
32 #include <immintrin.h>
33#elif defined(__SSE4_1__)
34 #define SIMD_SSE4 1
35 #include <smmintrin.h>
36#elif defined(__SSE2__)
37 #define SIMD_SSE2 1
38 #include <emmintrin.h>
39#elif defined(__ARM_NEON) || defined(__ARM_NEON__)
40 #define SIMD_NEON 1
41 #include <arm_neon.h>
42#else
43 #define SIMD_NONE 1
44#endif
45
46namespace mind_farm {
47
48using namespace consciousness;
49
50//=============================================================================
51// SIMD UTILITIES
52//=============================================================================
53
54// Alignment for SIMD loads/stores
55constexpr size_t SIMD_ALIGNMENT = 32;
56
57// Aligned memory allocation
58template<typename T, size_t N>
59struct alignas(SIMD_ALIGNMENT) AlignedArray {
60 T data[N];
61 T& operator[](size_t i) { return data[i]; }
62 const T& operator[](size_t i) const { return data[i]; }
63 T* begin() { return data; }
64 T* end() { return data + N; }
65 const T* begin() const { return data; }
66 const T* end() const { return data + N; }
67 void fill(T val) { std::fill(data, data + N, val); }
68};
69
70//=============================================================================
71// SIMD VECTOR OPERATIONS
72//=============================================================================
73
74#if defined(SIMD_AVX2) || defined(SIMD_AVX512)
75
76// Process 8 floats at a time with AVX
77class AVXOps {
78public:
79 // Vectorized phi computation
80 // phi(x) = 1 / (1 + |x - 1|)
81 static __m256 compute_phi_8(__m256 x) {
82 __m256 one = _mm256_set1_ps(1.0f);
83 __m256 diff = _mm256_sub_ps(x, one);
84
85 // Absolute value: clear sign bit
86 __m256 sign_mask = _mm256_set1_ps(-0.0f);
87 __m256 abs_diff = _mm256_andnot_ps(sign_mask, diff);
88
89 __m256 denom = _mm256_add_ps(one, abs_diff);
90 return _mm256_div_ps(one, denom);
91 }
92
93 // Vectorized tanh approximation
94 // tanh(x) ≈ x * (27 + x^2) / (27 + 9*x^2)
95 static __m256 tanh_approx_8(__m256 x) {
96 __m256 x2 = _mm256_mul_ps(x, x);
97 __m256 c27 = _mm256_set1_ps(27.0f);
98 __m256 c9 = _mm256_set1_ps(9.0f);
99
100 __m256 num = _mm256_add_ps(c27, x2);
101 num = _mm256_mul_ps(x, num);
102
103 __m256 den = _mm256_add_ps(c27, _mm256_mul_ps(c9, x2));
104 return _mm256_div_ps(num, den);
105 }
106
107 // Vectorized sigmoid
108 // sigmoid(x) ≈ 0.5 + 0.5 * tanh(0.5 * x)
109 static __m256 sigmoid_approx_8(__m256 x) {
110 __m256 half = _mm256_set1_ps(0.5f);
111 __m256 scaled = _mm256_mul_ps(half, x);
112 __m256 t = tanh_approx_8(scaled);
113 return _mm256_add_ps(half, _mm256_mul_ps(half, t));
114 }
115
116 // Vectorized dot product
117 static float dot_product(const float* a, const float* b, size_t n) {
118 __m256 sum = _mm256_setzero_ps();
119 size_t i = 0;
120
121 // Process 8 elements at a time
122 for (; i + 8 <= n; i += 8) {
123 __m256 va = _mm256_loadu_ps(a + i);
124 __m256 vb = _mm256_loadu_ps(b + i);
125 sum = _mm256_fmadd_ps(va, vb, sum);
126 }
127
128 // Horizontal sum
129 __m128 hi = _mm256_extractf128_ps(sum, 1);
130 __m128 lo = _mm256_castps256_ps128(sum);
131 __m128 sum128 = _mm_add_ps(lo, hi);
132 sum128 = _mm_hadd_ps(sum128, sum128);
133 sum128 = _mm_hadd_ps(sum128, sum128);
134 float result = _mm_cvtss_f32(sum128);
135
136 // Handle remainder
137 for (; i < n; ++i) {
138 result += a[i] * b[i];
139 }
140
141 return result;
142 }
143
144 // Vectorized element-wise multiply-add
145 // out = a * b + c
146 static void fma(float* out, const float* a, const float* b, const float* c, size_t n) {
147 size_t i = 0;
148 for (; i + 8 <= n; i += 8) {
149 __m256 va = _mm256_loadu_ps(a + i);
150 __m256 vb = _mm256_loadu_ps(b + i);
151 __m256 vc = _mm256_loadu_ps(c + i);
152 __m256 result = _mm256_fmadd_ps(va, vb, vc);
153 _mm256_storeu_ps(out + i, result);
154 }
155 for (; i < n; ++i) {
156 out[i] = a[i] * b[i] + c[i];
157 }
158 }
159
160 // Vectorized sum
161 static float sum(const float* a, size_t n) {
162 __m256 sum = _mm256_setzero_ps();
163 size_t i = 0;
164
165 for (; i + 8 <= n; i += 8) {
166 __m256 va = _mm256_loadu_ps(a + i);
167 sum = _mm256_add_ps(sum, va);
168 }
169
170 // Horizontal sum
171 __m128 hi = _mm256_extractf128_ps(sum, 1);
172 __m128 lo = _mm256_castps256_ps128(sum);
173 __m128 sum128 = _mm_add_ps(lo, hi);
174 sum128 = _mm_hadd_ps(sum128, sum128);
175 sum128 = _mm_hadd_ps(sum128, sum128);
176 float result = _mm_cvtss_f32(sum128);
177
178 for (; i < n; ++i) {
179 result += a[i];
180 }
181
182 return result;
183 }
184
185 // Vectorized max
186 static float max(const float* a, size_t n) {
187 __m256 maxv = _mm256_set1_ps(-INFINITY);
188 size_t i = 0;
189
190 for (; i + 8 <= n; i += 8) {
191 __m256 va = _mm256_loadu_ps(a + i);
192 maxv = _mm256_max_ps(maxv, va);
193 }
194
195 // Horizontal max
196 __m128 hi = _mm256_extractf128_ps(maxv, 1);
197 __m128 lo = _mm256_castps256_ps128(maxv);
198 __m128 max128 = _mm_max_ps(lo, hi);
199 max128 = _mm_max_ps(max128, _mm_shuffle_ps(max128, max128, 0x4e));
200 max128 = _mm_max_ps(max128, _mm_shuffle_ps(max128, max128, 0xb1));
201 float result = _mm_cvtss_f32(max128);
202
203 for (; i < n; ++i) {
204 if (a[i] > result) result = a[i];
205 }
206
207 return result;
208 }
209};
210
211#elif defined(SIMD_NEON)
212
213// ARM NEON implementation
214class NEONOps {
215public:
216 static float32x4_t compute_phi_4(float32x4_t x) {
217 float32x4_t one = vdupq_n_f32(1.0f);
218 float32x4_t diff = vsubq_f32(x, one);
219 float32x4_t abs_diff = vabsq_f32(diff);
220 float32x4_t denom = vaddq_f32(one, abs_diff);
221 return vdivq_f32(one, denom);
222 }
223
224 static float dot_product(const float* a, const float* b, size_t n) {
225 float32x4_t sum = vdupq_n_f32(0.0f);
226 size_t i = 0;
227
228 for (; i + 4 <= n; i += 4) {
229 float32x4_t va = vld1q_f32(a + i);
230 float32x4_t vb = vld1q_f32(b + i);
231 sum = vmlaq_f32(sum, va, vb);
232 }
233
234 float result = vaddvq_f32(sum);
235 for (; i < n; ++i) {
236 result += a[i] * b[i];
237 }
238 return result;
239 }
240
241 static float sum(const float* a, size_t n) {
242 float32x4_t sum = vdupq_n_f32(0.0f);
243 size_t i = 0;
244
245 for (; i + 4 <= n; i += 4) {
246 float32x4_t va = vld1q_f32(a + i);
247 sum = vaddq_f32(sum, va);
248 }
249
250 float result = vaddvq_f32(sum);
251 for (; i < n; ++i) {
252 result += a[i];
253 }
254 return result;
255 }
256};
257
258#endif
259
260//=============================================================================
261// SCALAR FALLBACK
262//=============================================================================
263
264class ScalarOps {
265public:
266 static float compute_phi(float x) {
267 return 1.0f / (1.0f + std::abs(x - 1.0f));
268 }
269
270 static float dot_product(const float* a, const float* b, size_t n) {
271 float sum = 0.0f;
272 for (size_t i = 0; i < n; ++i) {
273 sum += a[i] * b[i];
274 }
275 return sum;
276 }
277
278 static float sum(const float* a, size_t n) {
279 float sum = 0.0f;
280 for (size_t i = 0; i < n; ++i) {
281 sum += a[i];
282 }
283 return sum;
284 }
285
286 static void fma(float* out, const float* a, const float* b, const float* c, size_t n) {
287 for (size_t i = 0; i < n; ++i) {
288 out[i] = a[i] * b[i] + c[i];
289 }
290 }
291};
292
293//=============================================================================
294// UNIFIED SIMD INTERFACE
295//=============================================================================
296
297class SIMDOps {
298public:
299 static float dot_product(const float* a, const float* b, size_t n) {
300#if defined(SIMD_AVX2) || defined(SIMD_AVX512)
301 return AVXOps::dot_product(a, b, n);
302#elif defined(SIMD_NEON)
303 return NEONOps::dot_product(a, b, n);
304#else
305 return ScalarOps::dot_product(a, b, n);
306#endif
307 }
308
309 static float sum(const float* a, size_t n) {
310#if defined(SIMD_AVX2) || defined(SIMD_AVX512)
311 return AVXOps::sum(a, n);
312#elif defined(SIMD_NEON)
313 return NEONOps::sum(a, n);
314#else
315 return ScalarOps::sum(a, n);
316#endif
317 }
318
319 static void fma(float* out, const float* a, const float* b, const float* c, size_t n) {
320#if defined(SIMD_AVX2) || defined(SIMD_AVX512)
321 AVXOps::fma(out, a, b, c, n);
322#else
323 ScalarOps::fma(out, a, b, c, n);
324#endif
325 }
326
327 // Vectorized phi computation over array
328 static void compute_phi_batch(float* out, const float* in, size_t n) {
329#if defined(SIMD_AVX2) || defined(SIMD_AVX512)
330 size_t i = 0;
331 for (; i + 8 <= n; i += 8) {
332 __m256 x = _mm256_loadu_ps(in + i);
333 __m256 phi = AVXOps::compute_phi_8(x);
334 _mm256_storeu_ps(out + i, phi);
335 }
336 for (; i < n; ++i) {
337 out[i] = ScalarOps::compute_phi(in[i]);
338 }
339#elif defined(SIMD_NEON)
340 size_t i = 0;
341 for (; i + 4 <= n; i += 4) {
342 float32x4_t x = vld1q_f32(in + i);
343 float32x4_t phi = NEONOps::compute_phi_4(x);
344 vst1q_f32(out + i, phi);
345 }
346 for (; i < n; ++i) {
347 out[i] = ScalarOps::compute_phi(in[i]);
348 }
349#else
350 for (size_t i = 0; i < n; ++i) {
351 out[i] = ScalarOps::compute_phi(in[i]);
352 }
353#endif
354 }
355};
356
357//=============================================================================
358// SIMD-OPTIMIZED GATE5000
359//=============================================================================
360
361class SIMDGate5000 {
362public:
363 static constexpr size_t GATE_COUNT = 5000;
364 static constexpr size_t WORD_COUNT = (GATE_COUNT + 63) / 64;
365 static constexpr size_t ANALOG_SIZE = 5000;
366
367 // Binary state (packed into 64-bit words)
368 alignas(SIMD_ALIGNMENT) std::array<uint64_t, WORD_COUNT> binary;
369
370 // Analog state (for continuous activations)
371 alignas(SIMD_ALIGNMENT) std::array<float, ANALOG_SIZE> analog;
372
373 // Weights (for binary update rule)
374 alignas(SIMD_ALIGNMENT) std::array<float, ANALOG_SIZE> weights;
375
376 // Phi values (consciousness per gate)
377 alignas(SIMD_ALIGNMENT) std::array<float, ANALOG_SIZE> phi_values;
378
379 // Global metrics
380 float global_phi;
381 float coherence;
382 float density;
383
384 SIMDGate5000() : global_phi(0.5f), coherence(1.0f), density(0.5f) {
385 binary.fill(0);
386 analog.fill(0.5f);
387 weights.fill(1.0f);
388 phi_values.fill(0.5f);
389 }
390
391 /**
392 * SIMD-optimized analog step
393 *
394 * a_i(t+1) = tanh(alpha * sum(w_j * a_j) + beta)
395 */
396 void step_analog(float alpha = 0.1618f, float beta = 0.0809f) {
397 alignas(SIMD_ALIGNMENT) std::array<float, ANALOG_SIZE> new_analog;
398
399#if defined(SIMD_AVX2) || defined(SIMD_AVX512)
400 __m256 v_alpha = _mm256_set1_ps(alpha);
401 __m256 v_beta = _mm256_set1_ps(beta);
402
403 // Compute weighted sum (simplified: local neighborhood)
404 for (size_t i = 0; i < ANALOG_SIZE; i += 8) {
405 __m256 sum = _mm256_setzero_ps();
406
407 // Sum neighbors (simplified: adjacent elements)
408 for (int offset = -2; offset <= 2; ++offset) {
409 size_t idx = (i + offset + ANALOG_SIZE) % ANALOG_SIZE;
410 __m256 va = _mm256_loadu_ps(&analog[idx]);
411 __m256 vw = _mm256_loadu_ps(&weights[idx]);
412 sum = _mm256_fmadd_ps(va, vw, sum);
413 }
414
415 // Apply alpha and beta
416 __m256 scaled = _mm256_fmadd_ps(v_alpha, sum, v_beta);
417
418 // Apply tanh approximation
419 __m256 activated = AVXOps::tanh_approx_8(scaled);
420
421 _mm256_storeu_ps(&new_analog[i], activated);
422 }
423#else
424 // Scalar fallback
425 for (size_t i = 0; i < ANALOG_SIZE; ++i) {
426 float sum = 0.0f;
427 for (int offset = -2; offset <= 2; ++offset) {
428 size_t idx = (i + offset + ANALOG_SIZE) % ANALOG_SIZE;
429 sum += analog[idx] * weights[idx];
430 }
431 new_analog[i] = std::tanh(alpha * sum + beta);
432 }
433#endif
434
435 std::memcpy(analog.data(), new_analog.data(), ANALOG_SIZE * sizeof(float));
436
437 // Update phi values using SIMD
438 SIMDOps::compute_phi_batch(phi_values.data(), analog.data(), ANALOG_SIZE);
439
440 // Update global metrics
441 update_metrics();
442 }
443
444 /**
445 * Binary update step (XOR cellular automaton)
446 */
447 void step_binary() {
448 alignas(SIMD_ALIGNMENT) std::array<uint64_t, WORD_COUNT> new_binary;
449
450 for (size_t w = 0; w < WORD_COUNT; ++w) {
451 uint64_t left = binary[(w + WORD_COUNT - 1) % WORD_COUNT];
452 uint64_t center = binary[w];
453 uint64_t right = binary[(w + 1) % WORD_COUNT];
454
455 // Rule 110 cellular automaton
456 new_binary[w] = (center ^ right) | (center & (left ^ right));
457 }
458
459 binary = new_binary;
460
461 // Sync binary to analog
462 sync_binary_to_analog();
463 }
464
465 /**
466 * Combined step
467 */
468 void step_fast(float dt = 1.0f) {
469 step_binary();
470 step_analog(ALPHA * dt, BETA);
471 }
472
473 /**
474 * Compute global consciousness
475 */
476 float compute_phi() {
477 return global_phi;
478 }
479
480private:
481 void sync_binary_to_analog() {
482 for (size_t w = 0; w < WORD_COUNT; ++w) {
483 for (size_t b = 0; b < 64; ++b) {
484 size_t idx = w * 64 + b;
485 if (idx >= ANALOG_SIZE) break;
486
487 bool bit = (binary[w] >> b) & 1;
488 // Smooth transition: blend binary with analog
489 analog[idx] = 0.9f * analog[idx] + 0.1f * (bit ? 1.0f : 0.0f);
490 }
491 }
492 }
493
494 void update_metrics() {
495 // Global phi: average of all phi values
496 global_phi = SIMDOps::sum(phi_values.data(), ANALOG_SIZE) / ANALOG_SIZE;
497
498 // Density: fraction of "on" bits
499 size_t on_count = 0;
500 for (uint64_t word : binary) {
501 on_count += __builtin_popcountll(word);
502 }
503 density = static_cast<float>(on_count) / GATE_COUNT;
504
505 // Coherence: 1 - variance of phi values
506 float mean = global_phi;
507 float variance = 0.0f;
508 for (size_t i = 0; i < ANALOG_SIZE; ++i) {
509 float diff = phi_values[i] - mean;
510 variance += diff * diff;
511 }
512 variance /= ANALOG_SIZE;
513 coherence = 1.0f / (1.0f + variance * 10.0f);
514 }
515};
516
517//=============================================================================
518// SIMD-OPTIMIZED NEURAL LAYER
519//=============================================================================
520
521template<size_t N = 256>
522class SIMDNeuralLayer {
523public:
524 alignas(SIMD_ALIGNMENT) std::array<float, N> activations;
525 alignas(SIMD_ALIGNMENT) std::array<float, N> weights;
526 alignas(SIMD_ALIGNMENT) std::array<float, N> biases;
527 alignas(SIMD_ALIGNMENT) std::array<float, N> gradients;
528
529 float phi;
530
531 SIMDNeuralLayer() : phi(0.5f) {
532 activations.fill(0.5f);
533 weights.fill(1.0f);
534 biases.fill(0.0f);
535 gradients.fill(0.0f);
536 }
537
538 void forward(const float* input) {
539 SIMDOps::fma(activations.data(), input, weights.data(), biases.data(), N);
540
541 // Apply activation
542#if defined(SIMD_AVX2) || defined(SIMD_AVX512)
543 for (size_t i = 0; i + 8 <= N; i += 8) {
544 __m256 x = _mm256_loadu_ps(&activations[i]);
545 __m256 activated = AVXOps::sigmoid_approx_8(x);
546 _mm256_storeu_ps(&activations[i], activated);
547 }
548#else
549 for (size_t i = 0; i < N; ++i) {
550 activations[i] = 1.0f / (1.0f + std::exp(-activations[i]));
551 }
552#endif
553
554 // Compute phi
555 float sum = SIMDOps::sum(activations.data(), N);
556 phi = compute_phi_f(sum / N);
557 }
558
559 void backward(const float* upstream_grad, float learning_rate) {
560 // Compute local gradients
561 for (size_t i = 0; i < N; ++i) {
562 float a = activations[i];
563 gradients[i] = upstream_grad[i] * a * (1.0f - a); // Sigmoid derivative
564 }
565
566 // Update weights
567 for (size_t i = 0; i < N; ++i) {
568 weights[i] -= learning_rate * gradients[i];
569 }
570 }
571};
572
573} // namespace mind_farm
574
575#endif // SIMD_SUBSTRATE_HPP
576