libgomp testsuite: OpenACC C++ testing.
[official-gcc.git] / libgomp / testsuite / libgomp.oacc-c-c++-common / context-2.c
blob16464d56b39f798b1618024df12e7af597ac4c2d
1 /* { dg-do run { target openacc_nvidia_accel_selected } } */
2 /* { dg-additional-options "-lcuda -lcublas -lcudart" } */
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <cuda.h>
7 #include <cuda_runtime_api.h>
8 #include <cublas_v2.h>
9 #include <openacc.h>
11 void
12 saxpy (int n, float a, float *x, float *y)
14 int i;
16 for (i = 0; i < n; i++)
18 y[i] = a * x[i] + y[i];
22 void
23 context_check (CUcontext ctx1)
25 CUcontext ctx2, ctx3;
26 CUresult r;
28 r = cuCtxGetCurrent (&ctx2);
29 if (r != CUDA_SUCCESS)
31 fprintf (stderr, "cuCtxGetCurrent failed: %d\n", r);
32 exit (EXIT_FAILURE);
35 if (ctx1 != ctx2)
37 fprintf (stderr, "new context established\n");
38 exit (EXIT_FAILURE);
41 ctx3 = (CUcontext) acc_get_current_cuda_context ();
43 if (ctx1 != ctx3)
45 fprintf (stderr, "acc_get_current_cuda_context returned wrong value\n");
46 exit (EXIT_FAILURE);
49 return;
52 int
53 main (int argc, char **argv)
55 cublasStatus_t s;
56 cudaError_t e;
57 cublasHandle_t h;
58 CUcontext pctx, ctx;
59 CUresult r;
60 int dev;
61 int i;
62 const int N = 256;
63 float *h_X, *h_Y1, *h_Y2;
64 float *d_X,*d_Y;
65 float alpha = 2.0f;
66 float error_norm;
67 float ref_norm;
69 /* Test 2 - cuBLAS creates, OpenACC shares. */
71 s = cublasCreate (&h);
72 if (s != CUBLAS_STATUS_SUCCESS)
74 fprintf (stderr, "cublasCreate failed: %d\n", s);
75 exit (EXIT_FAILURE);
78 r = cuCtxGetCurrent (&pctx);
79 if (r != CUDA_SUCCESS)
81 fprintf (stderr, "cuCtxGetCurrent failed: %d\n", r);
82 exit (EXIT_FAILURE);
85 e = cudaGetDevice (&dev);
86 if (e != cudaSuccess)
88 fprintf (stderr, "cudaGetDevice failed: %d\n", e);
89 exit (EXIT_FAILURE);
92 acc_set_device_num (dev, acc_device_nvidia);
94 h_X = (float *) malloc (N * sizeof (float));
95 if (h_X == 0)
97 fprintf (stderr, "malloc failed: for h_X\n");
98 exit (EXIT_FAILURE);
101 h_Y1 = (float *) malloc (N * sizeof (float));
102 if (h_Y1 == 0)
104 fprintf (stderr, "malloc failed: for h_Y1\n");
105 exit (EXIT_FAILURE);
108 h_Y2 = (float *) malloc (N * sizeof (float));
109 if (h_Y2 == 0)
111 fprintf (stderr, "malloc failed: for h_Y2\n");
112 exit (EXIT_FAILURE);
115 for (i = 0; i < N; i++)
117 h_X[i] = rand () / (float) RAND_MAX;
118 h_Y2[i] = h_Y1[i] = rand () / (float) RAND_MAX;
121 d_X = (float *) acc_copyin (&h_X[0], N * sizeof (float));
122 if (d_X == NULL)
124 fprintf (stderr, "copyin error h_X\n");
125 exit (EXIT_FAILURE);
128 context_check (pctx);
130 d_Y = (float *) acc_copyin (&h_Y1[0], N * sizeof (float));
131 if (d_Y == NULL)
133 fprintf (stderr, "copyin error h_Y1\n");
134 exit (EXIT_FAILURE);
137 context_check (pctx);
139 s = cublasSaxpy (h, N, &alpha, d_X, 1, d_Y, 1);
140 if (s != CUBLAS_STATUS_SUCCESS)
142 fprintf (stderr, "cublasSaxpy failed: %d\n", s);
143 exit (EXIT_FAILURE);
146 context_check (pctx);
148 acc_memcpy_from_device (&h_Y1[0], d_Y, N * sizeof (float));
150 context_check (pctx);
152 #pragma acc parallel copyin (h_X[0:N]), copy (h_Y2[0:N]) copyin (alpha)
154 int i;
156 for (i = 0; i < N; i++)
158 h_Y2[i] = alpha * h_X[i] + h_Y2[i];
162 context_check (pctx);
164 error_norm = 0;
165 ref_norm = 0;
167 for (i = 0; i < N; ++i)
169 float diff;
171 diff = h_Y1[i] - h_Y2[i];
172 error_norm += diff * diff;
173 ref_norm += h_Y2[i] * h_Y2[i];
176 error_norm = (float) sqrt ((double) error_norm);
177 ref_norm = (float) sqrt ((double) ref_norm);
179 if ((fabs (ref_norm) < 1e-7) || ((error_norm / ref_norm) >= 1e-6f))
181 fprintf (stderr, "math error\n");
182 exit (EXIT_FAILURE);
185 free (h_X);
186 free (h_Y1);
187 free (h_Y2);
189 acc_free (d_X);
190 acc_free (d_Y);
192 context_check (pctx);
194 s = cublasDestroy (h);
195 if (s != CUBLAS_STATUS_SUCCESS)
197 fprintf (stderr, "cublasDestroy failed: %d\n", s);
198 exit (EXIT_FAILURE);
201 acc_shutdown (acc_device_nvidia);
203 r = cuCtxGetCurrent (&ctx);
204 if (r != CUDA_SUCCESS)
206 fprintf (stderr, "cuCtxGetCurrent failed: %d\n", r);
207 exit (EXIT_FAILURE);
210 if (!ctx)
212 fprintf (stderr, "Expected context\n");
213 exit (EXIT_FAILURE);
216 if (pctx != ctx)
218 fprintf (stderr, "Unexpected new context\n");
219 exit (EXIT_FAILURE);
222 return EXIT_SUCCESS;