Kernels
File size: 1,563 Bytes
e873e70
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// Run relu on the Intel UHD 770 iGPU (SYCL, Level-Zero/OpenCL). Shared DDR5 memory.
#include <sycl/sycl.hpp>
#include <cstdio>
#include <vector>
#include <chrono>
#include <algorithm>
using namespace sycl;

int main(){
  queue q{gpu_selector_v};
  auto d=q.get_device();
  printf("device: %s\n", d.get_info<info::device::name>().c_str());
  printf("  compute units: %u, global mem: %.2f GB\n",
         d.get_info<info::device::max_compute_units>(),
         d.get_info<info::device::global_mem_size>()/1e9);
  const size_t n=64ull*1024*1024;                 // 256 MB/array
  float* in =malloc_device<float>(n,q);
  float* out=malloc_device<float>(n,q);
  if(!in||!out){ printf("alloc failed\n"); return 1; }
  std::vector<float> h(n);
  for(size_t i=0;i<n;++i) h[i]=((i&1)?-1.f:1.f)*float(i%97);
  q.memcpy(in,h.data(),n*4).wait();
  double gb=2.0*n*4/1e9;

  auto run=[&](){ q.parallel_for(range<1>(n),[=](id<1> i){ out[i]=in[i]>0.f?in[i]:0.f; }).wait(); };
  for(int w=0;w<5;++w) run();                      // warmup (JIT compile)
  std::vector<float> o(n); q.memcpy(o.data(),out,n*4).wait();
  bool ok=true; for(size_t i=0;i<n&&ok;++i){ float e=h[i]>0?h[i]:0; if(o[i]!=e) ok=false; }

  double best=1e30;
  for(int r=0;r<12;++r){
    auto a=std::chrono::high_resolution_clock::now(); run();
    auto b=std::chrono::high_resolution_clock::now();
    best=std::min(best,std::chrono::duration<double>(b-a).count());
  }
  printf("iGPU relu (fp32, 64M): %.1f GB/s  (%.2f ms)  %s\n", gb/best, best*1e3, ok?"OK":"FAIL");
  free(in,q); free(out,q);
  return 0;
}