Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -161,4 +161,4 @@
},
"nbformat": 4,
"nbformat_minor": 4
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/bin/bash
source /opt/intel/inteloneapi/setvars.sh > /dev/null 2>&1
source /opt/intel/oneapi/setvars.sh > /dev/null 2>&1
/bin/echo "##" $(whoami) "is compiling Welcome Module-- 1 of 1 hello.cpp"
dpcpp src/hello.cpp -o src/hello
src/hello
if [ $? -eq 0 ]; then src/hello; fi

Binary file not shown.

This file was deleted.

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright Intel Corporation
Copyright 2020 Intel Corporation

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,27 +22,28 @@ void work(queue &q) {
// is allocated. The associated with vector1_accessor set to read/write gets
// the contents of the buffer.
int vector1[N] = {10, 10};
auto R = range(N);

std::cout << "Input : " << vector1[0] << ", " << vector1[1] << std::endl;

// ### Step 2 - Add another input vector - vector2
// Uncomment the following line to add input vector2
//int vector2[N] = {20,20};
//int vector2[N] = {20, 20};

// ### Step 3 - Print out for vector2
// Uncomment the following line
//std::cout << "Input : " << vector2[0] << ", " << vector2[1] << std::endl;
buffer<int, 1> vector1_buffer(vector1, range<1>(N));
buffer vector1_buffer(vector1,R);

// ### Step 4 - Add another Sycl buffer - vector2_buffer
// Uncomment the following line
//buffer<int, 1> vector2_buffer(vector2, range<1>(N));
//buffer vector2_buffer(vector2,R);
q.submit([&](handler &h) {
auto vector1_accessor =
vector1_buffer.get_access<access::mode::read_write>(h);
accessor vector1_accessor (vector1_buffer,h);

// Step 5 - add an accessor for vector2_buffer
// Look in the source code for the comment
//auto vector2_accessor = vector2_buffer.get_access <access::mode::read >(h);
// Uncomment the following line to add an accessor for vector 2
//accessor vector2_accessor (vector2_buffer,h,read_only);

h.parallel_for<class test>(range<1>(N), [=](id<1> index) {
// ### Step 6 - Replace the existing vector1_accessor to accumulate
Expand All @@ -55,7 +56,7 @@ void work(queue &q) {
});
});
q.wait();
vector1_buffer.get_access<access::mode::read>();
host_accessor h_a(vector1_buffer,read_only);
std::cout << "Output : " << vector1[0] << ", " << vector1[1] << std::endl;
}

Expand All @@ -73,4 +74,4 @@ int main() {
std::cerr << "Unknown exception" << std::endl;
std::terminate();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,78 @@
"<img src=\"Assets/workflow.png\">\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## oneAPI Programming models"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Platform Model\n",
"\n",
"The platform model for oneAPI is based upon the SYCL* platform model. It specifies a host controlling one or more devices. A host is the computer, typically a CPU-based system executing the primary portion of a program, specifically the application scope and the command group scope. \n",
"\n",
"The host coordinates and controls the compute work that is performed on the devices. A device is an accelerator, a specialized component containing compute resources that can quickly execute a subset of operations typically more efficiently than the CPUs in the system. Each device contains one or more compute units that can execute several operations in parallel. Each compute unit contains one or more processing elements that serve as the individual engine for computation.\n",
"\n",
"The following figure provides a visual depiction of the relationships in the platform model. One host communicates with one or more devices. Each device can contain one or more compute units. Each compute unit can contain one or more processing elements. In this example, the CPU in a desktop computer is the host and it can also be made available as a device in a platform configuration.\n",
"\n",
"<img src=\"Assets/plat30.png\">\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Execution Model\n",
"\n",
"The execution model is based upon the SYCL* execution model. It defines and specifies how code, termed kernels, execute on the devices and interact with the controlling host.\n",
"The host execution model coordinates execution and data management between the host and devices via command groups. The command groups, which are groupings of commands like kernel invocation and accessors, are submitted to queues for execution.\n",
"\n",
"Accessors, which are formally part of the memory model, also communicate ordering requirements of execution. A program employing the execution model declares and instantiates queues. Queues can execute with an in-order or out-of-order policy controllable by the program. In-order execution is an Intel extension.\n",
"\n",
"The device execution model specifies how computation is accomplished on the accelerator. Compute ranging from small one-dimensional data to large multidimensional data sets are allocated across a hierarchy of ND-ranges, work-groups, sub-groups (Intel extension), and work-items, which are all specified when the work is submitted to the command queue.\n",
"\n",
"It is important to note that the actual kernel code represents the work that is executed for one work-item. The code outside of the kernel controls just how much parallelism is executed; the amount and distribution of the work is controlled by specification of the sizes of the ND-range and work-group.\n",
"\n",
"\n",
"The following figure depicts the relationship between an ND-range, work-group, sub-group, and work-item. The total amount of work is specified by the ND-range size. The grouping of the work is specified by the work-group size. The example shows the ND-range size of X * Y * Z, work-group size of X’ * Y’ * Z’, and subgroup size of X’. Therefore, there are X * Y * Z work-items. There are (X * Y * Z) / (X’ * Y’ * Z’) work-groups and (X * Y * Z) / X’ subgroups.\n",
"\n",
"<img src=\"Assets/kernel30.png\">\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Memory Model\n",
"\n",
"The memory model for oneAPI is based upon the SYCL* memory model. It defines how the host and devices interact with memory. It coordinates the allocation and management of memory between the host and devices. The memory model is an abstraction that aims to generalize across and be adaptable to the different possible host and device configurations.\n",
"\n",
"In this model, memory resides upon and is owned by either the host or the device and is specified by declaring a memory object. There are two different types of memory objects, buffers and images. Interaction of these memory objects between the host and device is accomplished via an accessor, which communicates the desired location of access, such as host or device, and the particular mode of access, such as read or write.\n",
"\n",
"Consider a case where memory is allocated on the host through a traditional malloc call. Once the memory is allocated on the host, a buffer object is created, which enables the host allocated memory to be communicated to the device. The buffer class communicates the type and number of items of that type to be communicated to the device for computation. Once a buffer is created on the host, the type of access allowed on the device is communicated via an accessor object, which specifies the type of access to the buffer.\n",
"\n",
"<img src=\"Assets/memory.png\">"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Kernel Programming Model\n",
"The kernel programming model for oneAPI is based upon the SYCL* kernel programming model. It enables explicit parallelism between the host and device. The parallelism is explicit in the sense that the programmer determines what code executes on the host and device; it is not automatic. The kernel code executes on the accelerator. \n",
"\n",
"Programs employing the oneAPI programming model support single source, meaning the host code and device code can be in the same source file. However, there are differences between the source code accepted in the host code and the device code with respect to language conformance and language features. \n",
"\n",
"The SYCL Specification defines in detail the required language features for host code and device code. The following is a summary that is specific to the oneAPI product."
]
},
{
"cell_type": "markdown",
"metadata": {},
Expand Down Expand Up @@ -300,27 +372,28 @@
" // is allocated. The associated with vector1_accessor set to read/write gets\n",
" // the contents of the buffer.\n",
" int vector1[N] = {10, 10};\n",
" auto R = range(N);\n",
" \n",
" std::cout << \"Input : \" << vector1[0] << \", \" << vector1[1] << std::endl;\n",
"\n",
" // ### Step 2 - Add another input vector - vector2\n",
" // Uncomment the following line to add input vector2\n",
" //int vector2[N] = {20,20};\n",
" //int vector2[N] = {20, 20};\n",
"\n",
" // ### Step 3 - Print out for vector2\n",
" // Uncomment the following line\n",
" //std::cout << \"Input : \" << vector2[0] << \", \" << vector2[1] << std::endl;\n",
" buffer<int, 1> vector1_buffer(vector1, range<1>(N));\n",
" buffer vector1_buffer(vector1,R);\n",
"\n",
" // ### Step 4 - Add another Sycl buffer - vector2_buffer\n",
" // Uncomment the following line\n",
" //buffer<int, 1> vector2_buffer(vector2, range<1>(N));\n",
" //buffer vector2_buffer(vector2,R);\n",
" q.submit([&](handler &h) {\n",
" auto vector1_accessor =\n",
" vector1_buffer.get_access<access::mode::read_write>(h);\n",
" accessor vector1_accessor (vector1_buffer,h);\n",
"\n",
" // Step 5 - add an accessor for vector2_buffer\n",
" // Uncomment the following line to add an accessor for vector 2\n",
" //auto vector2_accessor = vector2_buffer.get_access <access::mode::read >(h);\n",
" //accessor vector2_accessor (vector2_buffer,h,read_only);\n",
"\n",
" h.parallel_for<class test>(range<1>(N), [=](id<1> index) {\n",
" // ### Step 6 - Replace the existing vector1_accessor to accumulate\n",
Expand All @@ -333,7 +406,7 @@
" });\n",
" });\n",
" q.wait();\n",
" vector1_buffer.get_access<access::mode::read>();\n",
" host_accessor h_a(vector1_buffer,read_only);\n",
" std::cout << \"Output : \" << vector1[0] << \", \" << vector1[1] << std::endl;\n",
"}\n",
"\n",
Expand Down Expand Up @@ -474,6 +547,13 @@
},
"toc_section_display": true,
"toc_window_display": true
},
"widgets": {
"application/vnd.jupyter.widget-state+json": {
"state": {},
"version_major": 2,
"version_minor": 0
}
}
},
"nbformat": 4,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/bin/bash
source /opt/intel/inteloneapi/setvars.sh > /dev/null 2>&1
source /opt/intel/oneapi/setvars.sh > /dev/null 2>&1
/bin/echo "##" $(whoami) is compiling DPCPP_Essentials Module1 -- oneAPI Intro sample - 2 of 2 simple-vector-incr.cpp
dpcpp lab/simple-vector-incr.cpp -o bin/simple-vector-incr
bin/simple-vector-incr
if [ $? -eq 0 ]; then bin/simple-vector-incr; fi
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/bin/bash
source /opt/intel/inteloneapi/setvars.sh > /dev/null 2>&1
source /opt/intel/oneapi/setvars.sh > /dev/null 2>&1
/bin/echo "##" $(whoami) is compiling DPCPP_Essentials Module1 -- oneAPI Intro sample - 1 of 2 simple.cpp
dpcpp lab/simple.cpp -o bin/simple
bin/simple
if [ $? -eq 0 ]; then bin/simple; fi

Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
//==============================================================
// Copyright © 2020 Intel Corporation
//
// SPDX-License-Identifier: MIT
// =============================================================

#include <CL/sycl.hpp>
using namespace sycl;
//N is set as 2 as this is just for demonstration purposes. Even if you make N bigger than 2 the program still
//counts N as only 2 as the first 2 elements are only initialized here and the rest all becomes zero.
static const size_t N = 2;

// ############################################################
// work

void work(queue &q) {
std::cout << "Device : "
<< q.get_device().get_info<info::device::name>()
<< std::endl;
// ### Step 1 - Inspect
// The code presents one input buffer (vector1) for which Sycl buffer memory
// is allocated. The associated with vector1_accessor set to read/write gets
// the contents of the buffer.
int vector1[N] = {10, 10};
std::cout << "Input : " << vector1[0] << ", " << vector1[1] << std::endl;

// ### Step 2 - Add another input vector - vector2
// Uncomment the following line to add input vector2
//int vector2[N] = {20,20};

// ### Step 3 - Print out for vector2
// Uncomment the following line
//std::cout << "Input : " << vector2[0] << ", " << vector2[1] << std::endl;
buffer<int, 1> vector1_buffer(vector1, range<1>(N));

// ### Step 4 - Add another Sycl buffer - vector2_buffer
// Uncomment the following line
//buffer<int, 1> vector2_buffer(vector2, range<1>(N));
q.submit([&](handler &h) {
auto vector1_accessor =
vector1_buffer.get_access<access::mode::read_write>(h);

// Step 5 - add an accessor for vector2_buffer
// Look in the source code for the comment
//auto vector2_accessor = vector2_buffer.get_access <access::mode::read >(h);

h.parallel_for<class test>(range<1>(N), [=](id<1> index) {
// ### Step 6 - Replace the existing vector1_accessor to accumulate
// vector2_accessor
// Comment the following line
vector1_accessor[index] += 1;

// Uncomment the following line
//vector1_accessor[index] += vector2_accessor[index];
});
});
q.wait();
vector1_buffer.get_access<access::mode::read>();
std::cout << "Output : " << vector1[0] << ", " << vector1[1] << std::endl;
}

// ############################################################
// entry point for the program

int main() {
try {
queue q;
work(q);
} catch (exception e) {
std::cerr << "Exception: " << e.what() << std::endl;
std::terminate();
} catch (...) {
std::cerr << "Unknown exception" << std::endl;
std::terminate();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,27 +22,28 @@ void work(queue &q) {
// is allocated. The associated with vector1_accessor set to read/write gets
// the contents of the buffer.
int vector1[N] = {10, 10};
auto R = range(N);

std::cout << "Input : " << vector1[0] << ", " << vector1[1] << std::endl;

// ### Step 2 - Add another input vector - vector2
// Uncomment the following line to add input vector2
//int vector2[N] = {20,20};
//int vector2[N] = {20, 20};

// ### Step 3 - Print out for vector2
// Uncomment the following line
//std::cout << "Input : " << vector2[0] << ", " << vector2[1] << std::endl;
buffer<int, 1> vector1_buffer(vector1, range<1>(N));
buffer vector1_buffer(vector1,R);

// ### Step 4 - Add another Sycl buffer - vector2_buffer
// Uncomment the following line
//buffer<int, 1> vector2_buffer(vector2, range<1>(N));
//buffer vector2_buffer(vector2,R);
q.submit([&](handler &h) {
auto vector1_accessor =
vector1_buffer.get_access<access::mode::read_write>(h);
accessor vector1_accessor (vector1_buffer,h);

// Step 5 - add an accessor for vector2_buffer
// Look in the source code for the comment
//auto vector2_accessor = vector2_buffer.get_access <access::mode::read >(h);
// Uncomment the following line to add an accessor for vector 2
//accessor vector2_accessor (vector2_buffer,h,read_only);

h.parallel_for<class test>(range<1>(N), [=](id<1> index) {
// ### Step 6 - Replace the existing vector1_accessor to accumulate
Expand All @@ -55,7 +56,7 @@ void work(queue &q) {
});
});
q.wait();
vector1_buffer.get_access<access::mode::read>();
host_accessor h_a(vector1_buffer,read_only);
std::cout << "Output : " << vector1[0] << ", " << vector1[1] << std::endl;
}

Expand All @@ -73,4 +74,4 @@ int main() {
std::cerr << "Unknown exception" << std::endl;
std::terminate();
}
}
}
Loading