adhokshaj

C++ AMP sample

Jan 10th, 2013
25
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.66 KB | None | 0 0
  1. #include <amp.h>
  2. #include <iostream>
  3. #include <assert.h>
  4. #include <conio.h>
  5.  
  6. using namespace concurrency;
  7.  
  8. #define DATA_TYPE float
  9.  
  10. //----------------------------------------------------------------------------
  11. // Generate random data
  12. //----------------------------------------------------------------------------
  13. template<typename _type>
  14. void initialize_array(std::vector<_type> &v_data, unsigned size)
  15. {
  16.     for(unsigned i=0; i<size; ++i)
  17.     {
  18.         v_data[i] = (_type)((_type)rand() * 100 / (_type)(RAND_MAX + 1));
  19.     }
  20. }
  21.  
  22. //----------------------------------------------------------------------------
  23. // Implement matrix multiplication on CPU - N cube algorithm
  24. //----------------------------------------------------------------------------
  25. template<typename _type>
  26. void mxm_single_cpu(int M, int N, int W, const std::vector<_type>& va, const std::vector<_type>& vb, std::vector<_type>& vresult)
  27. {
  28.     if ((va.size() != M*N) || (vb.size() != N*W) || (vresult.size() != M*W))
  29.         throw "Expected matrix dimension result(M*W) = a(M*N) * b(N*W)";
  30.  
  31.     for(int k=0; k<M; ++k)
  32.     {
  33.         for(int j=0; j<W; ++j)
  34.         {
  35.             _type result = 0;
  36.  
  37.             for(int i=0; i<N; ++i)
  38.             {
  39.                 int idx_a = k * N + i;
  40.                 int idx_b = i * W + j;
  41.  
  42.                 result += va[idx_a] * vb[idx_b];
  43.             }
  44.  
  45.             vresult[k * W + j] = result;
  46.         }
  47.     }
  48. }
  49.  
  50. //----------------------------------------------------------------------------
  51. // Implement simple matrix multiplication on GPU using C++ AMP
  52. //----------------------------------------------------------------------------
  53. template<typename _type>
  54. void mxm_amp_simple(int M, int N, int W, const std::vector<_type>& va, const std::vector<_type>& vb, std::vector<_type>& vresult)
  55. {
  56.     if ((va.size() != M*N) || (vb.size() != N*W) || (vresult.size() != M*W))
  57.         throw "Expected matrix dimension result(M*W) = a(MxN) * b(N*W)";
  58.  
  59.     extent<2> e_a(M, N), e_b(N, W), e_c(M, W);
  60.  
  61.     // Copy in
  62.     array_view<const _type, 2> av_a(e_a, va);
  63.     array_view<const _type, 2> av_b(e_b, vb);
  64.     array_view<_type, 2> av_c(e_c, vresult);
  65.     av_c.discard_data();
  66.  
  67.     // Compute - outer 2 for loops of CPU is replaced by a parallel_for_each
  68.     parallel_for_each(av_c.extent, [=](index<2> idx) restrict(amp)
  69.         {
  70.             _type result = 0;
  71.  
  72.             for(int i = 0; i < av_a.extent[1]; ++i)
  73.             {
  74.                 index<2> idx_a(idx[0], i);
  75.                 index<2> idx_b(i, idx[1]);
  76.  
  77.                 result += av_a[idx_a] * av_b[idx_b];
  78.             }
  79.  
  80.             av_c[idx] = result;
  81.         });
  82.     // explicitly about copying out data
  83.     av_c.synchronize();
  84. }
  85.  
  86. template<typename _type>
  87. bool verify(std::vector<_type>& v_res, std::vector<_type>& v_ref, int len)
  88. {
  89.     bool passed = true;
  90.  
  91.     for (int i = 0; i < len; ++i)
  92.     {
  93.         if (v_res[i] != v_ref[i])
  94.         {
  95.              printf("v_res[%d] = %f, v_ref[%d] = %f\n", i, v_res[i], i, v_ref[i]);
  96.              passed = false;
  97.              break;
  98.         }
  99.     }
  100.  
  101.     return passed;
  102. }
  103.  
  104. template<>
  105. bool verify(std::vector<float>& v_res, std::vector<float>& v_ref, int len)
  106. {
  107.     bool passed = true;
  108.  
  109.     for (int i = 0; i < len; ++i)
  110.     {
  111.         if (fabs(v_res[i] - v_ref[i]) > 0.01)
  112.         {
  113.              printf("v_res[%d] = %f, v_ref[%d] = %f\n", i, v_res[i], i, v_ref[i]);
  114.              passed = false;
  115.              break;
  116.         }
  117.     }
  118.  
  119.     return passed;
  120. }
  121.  
  122. int main()
  123. {
  124.     accelerator default_device;
  125.     std::wcout << L"Using device : " << default_device.get_description() << std::endl;
  126.     if (default_device == accelerator(accelerator::direct3d_ref))
  127.         std::cout << "WARNING!! Running on very slow emulator! Only use this accelerator for debugging." << std::endl;
  128.  
  129.     srand(2012);
  130.  
  131.     const int M = 100;
  132.     const int N = 100;
  133.     const int W = 100;
  134.    
  135.     std::vector<DATA_TYPE> v_a(M * N);
  136.     std::vector<DATA_TYPE> v_b(N * W);
  137.     std::vector<DATA_TYPE> v_c_simple(M * W);
  138.     std::vector<DATA_TYPE> v_c_tiled(M * W);
  139.     std::vector<DATA_TYPE> v_ref(M * W);
  140.  
  141.     initialize_array(v_a, M * N);
  142.     initialize_array(v_b, N * W);
  143.  
  144.     assert((M!=0) && (W!=0) && (N!=0));
  145.  
  146.     printf("Matrix dimension C(%d x %d) = A(%d x %d) * B(%d x %d)\n", M, W, M, N, N, W);
  147.     printf("CPU(single core) exec ");
  148.     mxm_single_cpu(M, N, W, v_a, v_b, v_ref);
  149.     printf("completed.\n");
  150.  
  151.     printf("AMP Simple ");
  152.     mxm_amp_simple(M, N, W, v_a, v_b, v_c_simple);
  153.     printf("completed.\n");
  154.     printf("\t%s\n\n", verify(v_c_simple, v_ref, M * W) ? "Data matches" : "Data mismatch");
  155.  
  156.     _getch();
  157.     return 0;
  158. }
Advertisement
Add Comment
Please, Sign In to add comment