Science&Enigneering

SYCL sample and MD code

##- 2023. 3. 10. 11:21
728x90
#include <CL/sycl.hpp>
#include <iostream>

using namespace cl::sycl;

int main() {
  constexpr size_t N = 1024;
  
  std::vector<float> A(N);
  std::vector<float> B(N);
  std::vector<float> C(N);

  // Initialize A and B with some values
  for (size_t i = 0; i < N; ++i) {
    A[i] = static_cast<float>(i);
    B[i] = static_cast<float>(N - i);
  }

  // Create a queue to execute commands on a SYCL device
  queue q;

  // Create buffers for A, B, and C on the device
  buffer<float, 1> bufA(A.data(), N);
  buffer<float, 1> bufB(B.data(), N);
  buffer<float, 1> bufC(C.data(), N);

  // Submit a command group to the queue to perform the vector addition
  q.submit([&](handler& h) {
    // Get accessors to the buffers
    auto a = bufA.get_access<access::mode::read>(h);
    auto b = bufB.get_access<access::mode::read>(h);
    auto c = bufC.get_access<access::mode::write>(h);

    // Define a parallel_for_work_item kernel that performs the addition
    h.parallel_for_work_item(N, [=](id<1> i) {
      c[i] = a[i] + b[i];
    });
  });

  // Wait for the command group to finish and print the result
  q.wait();
  std::cout << "C[0] = " << C[0] << std::endl;

  return 0;
}

 

Very simple version of SYCL MD code generated by ChatGPT

 

#include <CL/sycl.hpp>
#include <vector>

using namespace cl::sycl;

// Particle structure
struct Particle {
  float3 pos;
  float3 vel;
};

int main() {
  constexpr int kNumParticles = 1000;
  constexpr float kBoxSize = 10.0f;
  constexpr float kTimeStep = 0.01f;
  constexpr float kMass = 1.0f;

  std::vector<Particle> particles(kNumParticles);

  // Initialize particle positions and velocities
  for (int i = 0; i < kNumParticles; ++i) {
    particles[i].pos = {(i % 10) * 1.1f, (i / 10) * 1.1f, 0.0f};
    particles[i].vel = {0.0f, 0.0f, 0.0f};
  }

  // Create a queue to execute commands on a SYCL device
  queue q;

  // Create a buffer for the particles on the device
  buffer<Particle, 1> bufParticles(particles.data(), kNumParticles);

  // Define a kernel that updates particle positions and velocities
  auto update_particles = [&](handler& h) {
    // Get an accessor to the particles buffer with read/write access
    auto particles_acc = bufParticles.get_access<access::mode::read_write>(h);

    // Define a parallel_for_work_item kernel that updates the particles
    h.parallel_for_work_item(kNumParticles, [=](id<1> i) {
      Particle& p = particles_acc[i];

      // Update velocity and position using the Verlet algorithm
      p.pos += p.vel * kTimeStep;
      p.vel *= 1.0f - kTimeStep;

      // Enforce periodic boundary conditions
      if (p.pos.x < 0.0f) p.pos.x += kBoxSize;
      if (p.pos.x >= kBoxSize) p.pos.x -= kBoxSize;
      if (p.pos.y < 0.0f) p.pos.y += kBoxSize;
      if (p.pos.y >= kBoxSize) p.pos.y -= kBoxSize;
      if (p.pos.z < 0.0f) p.pos.z += kBoxSize;
      if (p.pos.z >= kBoxSize) p.pos.z -= kBoxSize;
    });
  };

  // Perform the simulation
  for (int step = 0; step < 100; ++step) {
    // Update particles
    q.submit(update_particles);
    q.wait();
  }

  return 0;
}

 

300x250