complex matrix multiplication in python and pycuda

complex matrix multiplication in python and pycuda :)
mail@pastecode.io avatar
unknown
python
2 months ago
5.9 kB
2
Indexable
Never
import numpy as np
import pycuda.autoinit
import pycuda.driver as cuda
from pycuda.compiler import SourceModule
import matplotlib.pyplot as plt
from scipy.integrate import solve_ivp

class ChaoticAttractors:
    def __init__(self, num_points):
        self.num_points = num_points

    def lorenz_attractor(self, t, state, sigma=10.0, rho=28.0, beta=8.0/3.0):
        x, y, z = state
        dxdt = sigma * (y - x)
        dydt = x * (rho - z) - y
        dzdt = x * y - beta * z
        return [dxdt, dydt, dzdt]

    def rossler_attractor(self, t, state, a=0.2, b=0.2, c=5.7):
        x, y, z = state
        dxdt = -y - z
        dydt = x + a * y
        dzdt = b + z * (x - c)
        return [dxdt, dydt, dzdt]

    def generate_attractor_points(self):
        attractor_functions = [self.lorenz_attractor, self.rossler_attractor]
        attractor_func = np.random.choice(attractor_functions)
        t_span = np.linspace(0, 50, self.num_points)
        initial_state = np.random.rand(3)
        attractor_solution = solve_ivp(attractor_func, [t_span[0], t_span[-1]], initial_state, t_eval=t_span)
        return attractor_solution.y.T.astype(np.float32)

class VectorialModulation:
    def __init__(self, num_points):
        self.num_points = num_points
        self.attractor_generator = ChaoticAttractors(num_points)

    def spiral_cosine(self):
        theta = np.linspace(0, 4 * np.pi, self.num_points).astype(np.float32)
        x = np.cos(theta) * theta
        y = np.sin(theta) * theta
        return np.column_stack((x, y))

    def reverse_spiral_sine(self):
        theta = np.linspace(0, 4 * np.pi, self.num_points)[::-1].astype(np.float32)
        x = np.sin(theta) * theta
        y = np.cos(theta) * theta
        return np.column_stack((x, y))

    def vectorial_modulation(self, attractor_points, spiral_cosine_points, reverse_spiral_sine_points):
        modulation_kernel = """
        __global__ void vectorial_modulation(float *attractor_points, float *spiral_cosine_points, float *reverse_spiral_sine_points, float *modulated_points, int num_points)
        {
            int idx = blockIdx.x * blockDim.x + threadIdx.x;
            if (idx < num_points)
            {
                int offset = idx * 2;
                modulated_points[offset] = attractor_points[offset] * spiral_cosine_points[offset] * reverse_spiral_sine_points[offset];
                modulated_points[offset + 1] = attractor_points[offset + 1] * spiral_cosine_points[offset + 1] * reverse_spiral_sine_points[offset + 1];
            }
        }
        """

        modulation_module = SourceModule(modulation_kernel)
        modulation_function = modulation_module.get_function("vectorial_modulation")

        # Allocate device memory
        attractor_points_gpu = cuda.mem_alloc(attractor_points.nbytes)
        spiral_cosine_points_gpu = cuda.mem_alloc(spiral_cosine_points.nbytes)
        reverse_spiral_sine_points_gpu = cuda.mem_alloc(reverse_spiral_sine_points.nbytes)
        modulated_points_gpu = cuda.mem_alloc(attractor_points.nbytes)

        # Copy data to device
        cuda.memcpy_htod(attractor_points_gpu, attractor_points)
        cuda.memcpy_htod(spiral_cosine_points_gpu, spiral_cosine_points)
        cuda.memcpy_htod(reverse_spiral_sine_points_gpu, reverse_spiral_sine_points)

        # Define block and grid dimensions
        block_size = 256
        grid_size = (self.num_points + block_size - 1) // block_size

        # Execute the CUDA kernel
        modulation_function(attractor_points_gpu, spiral_cosine_points_gpu, reverse_spiral_sine_points_gpu, modulated_points_gpu, np.int32(self.num_points), block=(block_size, 1, 1), grid=(grid_size, 1))

        # Copy result back to host
        modulated_points = np.empty_like(attractor_points)
        cuda.memcpy_dtoh(modulated_points, modulated_points_gpu)

        return modulated_points

    def plot_modulated_points(self, attractor_points, modulated_points):
        plt.figure(figsize=(10, 5))
        plt.subplot(1, 2, 1)
        plt.plot(attractor_points[:, 0], attractor_points[:, 1], label='Attractor Points')
        plt.title('Chaotic Attractor')
        plt.subplot(1, 2, 2)
        plt.plot(modulated_points[:, 0], modulated_points[:, 1], label='Modulated Points')
        plt.title('Modulated Attractor')
        plt.show()

    def menu(self):
        while True:
            print("\nMenu:")
            print("1. Generate Chaotic Attractor")
            print("2. Modulate Attractor")
            print("3. Plot Modulated Points")
            print("4. Exit")

            choice = input("Enter your choice: ")

            if choice == '1':
                self.attractor_points = self.attractor_generator.generate_attractor_points()
                print("Chaotic attractor generated.")
            elif choice == '2':
                self.spiral_cosine_points = self.spiral_cosine()
                self.reverse_spiral_sine_points = self.reverse_spiral_sine()
                self.modulated_points = self.vectorial_modulation(self.attractor_points, self.spiral_cosine_points, self.reverse_spiral_sine_points)
                print("Attractor modulated.")
            elif choice == '3':
                try:
                    self.plot_modulated_points(self.attractor_points, self.modulated_points)
                except AttributeError:
                    print("Please generate and modulate attractor first.")
            elif choice == '4':
                print("Exiting...")
                break
            else:
                print("Invalid choice. Please try again.")

if __name__ == "__main__":
    num_points = 1000
    modulation_system = VectorialModulation(num_points)
    modulation_system.menu()
Leave a Comment