Skip to content

Instantly share code, notes, and snippets.

@DSCF-1224
Last active July 30, 2023 10:57
Show Gist options
  • Save DSCF-1224/bd511cdb10a8e08611a84e2dadf201e1 to your computer and use it in GitHub Desktop.
Save DSCF-1224/bd511cdb10a8e08611a84e2dadf201e1 to your computer and use it in GitHub Desktop.
Data Parallel C++

fig_1_1_hello.cpp

#include <iostream>
#include <sycl/sycl.hpp>

const std::string secret_string{ "Ifmmp-!xpsme\"\012J(n!tpssz-!Ebwf/!"    "J(n!bgsbje!J!dbo(u!ep!uibu/!.!IBM\01" };
const auto secret_string_size = secret_string.size();

int main(void)
{
  sycl::queue sycl_queue;

  char* result_string = sycl::malloc_shared<char>(secret_string_size, sycl_queue);

  std::memcpy(result_string, secret_string.data(), secret_string_size);

  sycl_queue.parallel_for(secret_string_size, [=](auto& i) {result_string[i] -= 1; }).wait();

  std::cout << result_string << std::endl;

  sycl::free(result_string, sycl_queue);

  return EXIT_SUCCESS;
}
Hello, world!   I'm sorry, Dave. I'm afraid I can't do that. - HAL

fig_1_3_race.cpp

#include <iostream>
#include <sycl/sycl.hpp>

const std::string secret_string{ "Ifmmp-!xpsme\"\012J(n!tpssz-!Ebwf/!"    "J(n!bgsbje!J!dbo(u!ep!uibu/!.!IBM\01" };
const auto secret_string_size = secret_string.size();

int main(void)
{
  sycl::queue sycl_queue;

  char* result_string = sycl::malloc_shared<char>(secret_string_size, sycl_queue);

  std::memcpy(result_string, secret_string.data(), secret_string_size);

  // Introduce potential data race!
  // We don't define a dependence to ensure correct ordering with later operations.
  // 
  // std::memcpy(result_string, secret_string.data(), secret_string_size);
  // 
  sycl_queue.memcpy(result_string, secret_string.data(), secret_string_size);

  sycl_queue.parallel_for(secret_string_size, [=](auto& i) {result_string[i] -= 1; }).wait();

  std::cout << result_string << std::endl;

  sycl::free(result_string, sycl_queue);

  return EXIT_SUCCESS;
}
Hello, world!   I'm sorry, Dave. I'm afraid I can't do that. - HAL

fig_2_10_gpu_selector.cpp

#include <iostream>
#include <sycl/sycl.hpp>

int main(void)
{
	// Create queue bound to an available GPU device
	sycl::queue sycl_queue{ sycl::gpu_selector_v };

	std::cout
		<< "Selected device: "
		<< sycl_queue.get_device().get_info<sycl::info::device::name>()
		<< std::endl;

	std::cout
		<< " -> Device vendor: "
		<< sycl_queue.get_device().get_info<sycl::info::device::vendor>()
		<< std::endl;

	return EXIT_SUCCESS;
}

fig_2_12_multiple_selectors.cpp

#include <iostream>
#include <string>
#include <sycl/ext/intel/fpga_extensions.hpp>
#include <sycl/sycl.hpp>

void output_dev_info(const sycl::device& device, const std::string& selector_name)
{
	std::cout
		<< selector_name << ": Selected device: "
		<< device.get_info<sycl::info::device::name>()
		<< std::endl;

	std::cout
		<< "                  -> Device vendor: "
		<< device.get_info<sycl::info::device::vendor>()
		<< std::endl;
}

int main(void)
{
	output_dev_info(sycl::device{ sycl::default_selector_v }, "default_selector_v");
	output_dev_info(sycl::device{ sycl::cpu_selector_v }, "cpu_selector_v");
	output_dev_info(sycl::device{ sycl::gpu_selector_v }, "gpu_selector_v");
	output_dev_info(sycl::device{ sycl::accelerator_selector_v }, "accelerator_selector_v");
	output_dev_info(sycl::device{ sycl::ext::intel::fpga_emulator_selector_v}, "fpga_emulator_selector_v");

	return EXIT_SUCCESS;
}

fig_2_13_gpu_plus_fpga.cpp

#include <iostream>
#include <sycl/ext/intel/fpga_extensions.hpp>
#include <sycl/sycl.hpp>

int main(void)
{
	sycl::queue my_gpu_queue(sycl::gpu_selector_v);
	sycl::queue my_fpga_queue(sycl::ext::intel::fpga_emulator_selector_v);

	std::cout
		<< "Selected device 1: "
		<< my_gpu_queue.get_device().get_info<sycl::info::device::name>()
		<< std::endl;

	std::cout
		<< "Selected device 2: "
		<< my_fpga_queue.get_device().get_info<sycl::info::device::name>()
		<< std::endl;

	return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment