Skip to content

Commit 67c7f84

Browse files
authored
Merge pull request oneapi-src#1762 from IgorOchocki/cuRAND_migration
Cu rand migration
2 parents 5494f57 + d2fdd95 commit 67c7f84

File tree

94 files changed

+10461
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

94 files changed

+10461
-0
lines changed
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
* Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
3+
*
4+
* Redistribution and use in source and binary forms, with or without
5+
* modification, are permitted provided that the following conditions
6+
* are met:
7+
* * Redistributions of source code must retain the above copyright
8+
* notice, this list of conditions and the following disclaimer.
9+
* * Redistributions in binary form must reproduce the above copyright
10+
* notice, this list of conditions and the following disclaimer in the
11+
* documentation and/or other materials provided with the distribution.
12+
* * Neither the name of NVIDIA CORPORATION nor the names of its
13+
* contributors may be used to endorse or promote products derived
14+
* from this software without specific prior written permission.
15+
*
16+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
17+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19+
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20+
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21+
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22+
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23+
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
24+
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27+
*/
28+
29+
#pragma once
30+
31+
#include <sycl/sycl.hpp>
32+
#include <dpct/dpct.hpp>
33+
#include <cstring>
34+
#include <stdexcept>
35+
#include <vector>
36+
#include <dpct/rng_utils.hpp>
37+
38+
// CUDA API error checking
39+
/*
40+
DPCT1001:0: The statement could not be removed.
41+
*/
42+
/*
43+
DPCT1000:1: Error handling if-stmt was detected but could not be rewritten.
44+
*/
45+
#define CUDA_CHECK(err) \
46+
do { \
47+
dpct::err0 err_ = (err); \
48+
if (err_ != 0) { \
49+
std::printf("CUDA error %d at %s:%d\n", err_, __FILE__, __LINE__); \
50+
throw std::runtime_error("CUDA error"); \
51+
} \
52+
} while (0)
53+
54+
// curand API error checking
55+
#define CURAND_CHECK(err) \
56+
do { \
57+
int err_ = (err); \
58+
if (err_ != 0) { \
59+
std::printf("curand error %d at %s:%d\n", err_, __FILE__, __LINE__); \
60+
throw std::runtime_error("curand error"); \
61+
} \
62+
} while (0)
63+
64+
template <typename T> void print_vector(const std::vector<T> &data);
65+
66+
template <> void print_vector(const std::vector<float> &data) {
67+
for (auto &i : data)
68+
std::printf("%0.6f\n", i);
69+
}
70+
71+
template <> void print_vector(const std::vector<unsigned int> &data) {
72+
for (auto &i : data)
73+
std::printf("%d\n", i);
74+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
/*
2+
* This program uses the host CURAND API to generate 100
3+
* pseudorandom floats.
4+
*/
5+
#include <sycl/sycl.hpp>
6+
#include <dpct/dpct.hpp>
7+
#include <cstdio>
8+
#include <cstdlib>
9+
#include <cstring>
10+
#include <stdexcept>
11+
#include <vector>
12+
#include <dpct/rng_utils.hpp>
13+
14+
#include "curand_utils.h"
15+
16+
using data_type = float;
17+
18+
void run_on_device(const int &n, const data_type &mean, const data_type &stddev,
19+
const unsigned long long &offset,
20+
const unsigned long long &seed,
21+
const curandOrdering_t &order,
22+
const dpct::rng::random_engine_type &rng,
23+
const dpct::queue_ptr &stream, dpct::rng::host_rng_ptr &gen,
24+
std::vector<data_type> &h_data) try {
25+
dpct::device_ext &dev_ct1 = dpct::get_current_device();
26+
sycl::queue &q_ct1 = dev_ct1.default_queue();
27+
28+
data_type *d_data = nullptr;
29+
30+
/* C data to device */
31+
CUDA_CHECK(DPCT_CHECK_ERROR(d_data = (data_type *)sycl::malloc_device(
32+
sizeof(data_type) * h_data.size(), q_ct1)));
33+
34+
/* Create pseudo-random number generator */
35+
CURAND_CHECK(DPCT_CHECK_ERROR(gen = dpct::rng::create_host_rng(
36+
dpct::rng::random_engine_type::mrg32k3a)));
37+
38+
/* Set cuRAND to stream */
39+
CURAND_CHECK(DPCT_CHECK_ERROR(gen->set_queue(stream)));
40+
41+
/* Set offset */
42+
CURAND_CHECK(DPCT_CHECK_ERROR(gen->skip_ahead(offset)));
43+
44+
/* Set ordering */
45+
/*
46+
DPCT1007:2: Migration of curandSetGeneratorOrdering is not supported.
47+
*/
48+
CURAND_CHECK(curandSetGeneratorOrdering(gen, order));
49+
50+
/* Set seed */
51+
CURAND_CHECK(DPCT_CHECK_ERROR(gen->set_seed(seed)));
52+
53+
/* Generate n floats on device */
54+
CURAND_CHECK(DPCT_CHECK_ERROR(
55+
gen->generate_lognormal(d_data, h_data.size(), mean, stddev)));
56+
57+
/* Copy data to host */
58+
CUDA_CHECK(DPCT_CHECK_ERROR(stream->memcpy(
59+
h_data.data(), d_data, sizeof(data_type) * h_data.size())));
60+
61+
/* Sync stream */
62+
CUDA_CHECK(DPCT_CHECK_ERROR(stream->wait()));
63+
64+
/* Cleanup */
65+
CUDA_CHECK(DPCT_CHECK_ERROR(sycl::free(d_data, q_ct1)));
66+
}
67+
catch (sycl::exception const &exc) {
68+
std::cerr << exc.what() << "Exception caught at file:" << __FILE__
69+
<< ", line:" << __LINE__ << std::endl;
70+
std::exit(1);
71+
}
72+
73+
void run_on_host(const int &n, const data_type &mean, const data_type &stddev,
74+
const unsigned long long &offset,
75+
const unsigned long long &seed, const curandOrdering_t &order,
76+
const dpct::rng::random_engine_type &rng,
77+
const dpct::queue_ptr &stream, dpct::rng::host_rng_ptr &gen,
78+
std::vector<data_type> &h_data) try {
79+
80+
/* Create pseudo-random number generator */
81+
CURAND_CHECK(DPCT_CHECK_ERROR(gen = dpct::rng::create_host_rng(
82+
dpct::rng::random_engine_type::mrg32k3a)));
83+
84+
/* Set cuRAND to stream */
85+
CURAND_CHECK(DPCT_CHECK_ERROR(gen->set_queue(stream)));
86+
87+
/* Set offset */
88+
CURAND_CHECK(DPCT_CHECK_ERROR(gen->skip_ahead(offset)));
89+
90+
/* Set ordering */
91+
/*
92+
DPCT1007:3: Migration of curandSetGeneratorOrdering is not supported.
93+
*/
94+
CURAND_CHECK(curandSetGeneratorOrdering(gen, order));
95+
96+
/* Set seed */
97+
CURAND_CHECK(DPCT_CHECK_ERROR(gen->set_seed(seed)));
98+
99+
/* Generate n floats on host */
100+
CURAND_CHECK(DPCT_CHECK_ERROR(
101+
gen->generate_lognormal(h_data.data(), h_data.size(), mean, stddev)));
102+
}
103+
catch (sycl::exception const &exc) {
104+
std::cerr << exc.what() << "Exception caught at file:" << __FILE__
105+
<< ", line:" << __LINE__ << std::endl;
106+
std::exit(1);
107+
}
108+
109+
int main(int argc, char *argv[]) try {
110+
dpct::device_ext &dev_ct1 = dpct::get_current_device();
111+
112+
dpct::queue_ptr stream = &dpct::get_default_queue();
113+
dpct::rng::host_rng_ptr gen = NULL;
114+
dpct::rng::random_engine_type rng = dpct::rng::random_engine_type::mrg32k3a;
115+
curandOrdering_t order = CURAND_ORDERING_PSEUDO_BEST;
116+
117+
const int n = 10;
118+
119+
const unsigned long long offset = 0ULL;
120+
const unsigned long long seed = 1234ULL;
121+
122+
const data_type mean = 1.0f;
123+
const data_type stddev = 2.0f;
124+
125+
/* Create stream */
126+
/*
127+
DPCT1025:4: The SYCL queue is created ignoring the flag and priority options.
128+
*/
129+
CUDA_CHECK(DPCT_CHECK_ERROR(stream = dev_ct1.create_queue()));
130+
131+
/* Allocate n floats on host */
132+
std::vector<data_type> h_data(n, 0);
133+
134+
run_on_host(n, mean, stddev, offset, seed, order, rng, stream, gen, h_data);
135+
136+
printf("Host\n");
137+
print_vector(h_data);
138+
printf("=====\n");
139+
140+
run_on_device(n, mean, stddev, offset, seed, order, rng, stream, gen, h_data);
141+
142+
printf("Device\n");
143+
print_vector(h_data);
144+
printf("=====\n");
145+
146+
/* Cleanup */
147+
CURAND_CHECK(DPCT_CHECK_ERROR(gen.reset()));
148+
149+
CUDA_CHECK(DPCT_CHECK_ERROR(dev_ct1.destroy_queue(stream)));
150+
151+
CUDA_CHECK(DPCT_CHECK_ERROR(dev_ct1.reset()));
152+
153+
return EXIT_SUCCESS;
154+
}
155+
catch (sycl::exception const &exc) {
156+
std::cerr << exc.what() << "Exception caught at file:" << __FILE__
157+
<< ", line:" << __LINE__ << std::endl;
158+
std::exit(1);
159+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
/*
2+
* This program uses the host CURAND API to generate 100
3+
* pseudorandom floats.
4+
*/
5+
#include <sycl/sycl.hpp>
6+
#include <dpct/dpct.hpp>
7+
#include <cstdio>
8+
#include <cstdlib>
9+
#include <cstring>
10+
#include <stdexcept>
11+
#include <vector>
12+
#include <dpct/rng_utils.hpp>
13+
14+
#include "curand_utils.h"
15+
16+
using data_type = float;
17+
18+
void run_on_device(const int &n, const data_type &mean, const data_type &stddev,
19+
const unsigned long long &offset,
20+
const unsigned long long &seed,
21+
const curandOrdering_t &order,
22+
const dpct::rng::random_engine_type &rng,
23+
const dpct::queue_ptr &stream, dpct::rng::host_rng_ptr &gen,
24+
std::vector<data_type> &h_data) try {
25+
dpct::device_ext &dev_ct1 = dpct::get_current_device();
26+
sycl::queue &q_ct1 = dev_ct1.default_queue();
27+
28+
data_type *d_data = nullptr;
29+
30+
/* C data to device */
31+
CUDA_CHECK(DPCT_CHECK_ERROR(d_data = (data_type *)sycl::malloc_device(
32+
sizeof(data_type) * h_data.size(), q_ct1)));
33+
34+
/* Create pseudo-random number generator */
35+
CURAND_CHECK(DPCT_CHECK_ERROR(gen = dpct::rng::create_host_rng(
36+
dpct::rng::random_engine_type::mrg32k3a)));
37+
38+
/* Set cuRAND to stream */
39+
CURAND_CHECK(DPCT_CHECK_ERROR(gen->set_queue(stream)));
40+
41+
/* Set offset */
42+
CURAND_CHECK(DPCT_CHECK_ERROR(gen->skip_ahead(offset)));
43+
44+
/* Set ordering */
45+
/*
46+
DPCT1007:2: Migration of curandSetGeneratorOrdering is not supported.
47+
*/
48+
CURAND_CHECK(curandSetGeneratorOrdering(gen, order));
49+
50+
/* Set seed */
51+
CURAND_CHECK(DPCT_CHECK_ERROR(gen->set_seed(seed)));
52+
53+
/* Generate n floats on device */
54+
CURAND_CHECK(DPCT_CHECK_ERROR(
55+
gen->generate_gaussian(d_data, h_data.size(), mean, stddev)));
56+
57+
/* Copy data to host */
58+
CUDA_CHECK(DPCT_CHECK_ERROR(stream->memcpy(
59+
h_data.data(), d_data, sizeof(data_type) * h_data.size())));
60+
61+
/* Sync stream */
62+
CUDA_CHECK(DPCT_CHECK_ERROR(stream->wait()));
63+
64+
/* Cleanup */
65+
CUDA_CHECK(DPCT_CHECK_ERROR(sycl::free(d_data, q_ct1)));
66+
}
67+
catch (sycl::exception const &exc) {
68+
std::cerr << exc.what() << "Exception caught at file:" << __FILE__
69+
<< ", line:" << __LINE__ << std::endl;
70+
std::exit(1);
71+
}
72+
73+
void run_on_host(const int &n, const data_type &mean, const data_type &stddev,
74+
const unsigned long long &offset,
75+
const unsigned long long &seed, const curandOrdering_t &order,
76+
const dpct::rng::random_engine_type &rng,
77+
const dpct::queue_ptr &stream, dpct::rng::host_rng_ptr &gen,
78+
std::vector<data_type> &h_data) try {
79+
80+
/* Create pseudo-random number generator */
81+
CURAND_CHECK(DPCT_CHECK_ERROR(gen = dpct::rng::create_host_rng(
82+
dpct::rng::random_engine_type::mrg32k3a)));
83+
84+
/* Set cuRAND to stream */
85+
CURAND_CHECK(DPCT_CHECK_ERROR(gen->set_queue(stream)));
86+
87+
/* Set offset */
88+
CURAND_CHECK(DPCT_CHECK_ERROR(gen->skip_ahead(offset)));
89+
90+
/* Set ordering */
91+
/*
92+
DPCT1007:3: Migration of curandSetGeneratorOrdering is not supported.
93+
*/
94+
CURAND_CHECK(curandSetGeneratorOrdering(gen, order));
95+
96+
/* Set seed */
97+
CURAND_CHECK(DPCT_CHECK_ERROR(gen->set_seed(seed)));
98+
99+
/* Generate n floats on host */
100+
CURAND_CHECK(DPCT_CHECK_ERROR(
101+
gen->generate_gaussian(h_data.data(), h_data.size(), mean, stddev)));
102+
}
103+
catch (sycl::exception const &exc) {
104+
std::cerr << exc.what() << "Exception caught at file:" << __FILE__
105+
<< ", line:" << __LINE__ << std::endl;
106+
std::exit(1);
107+
}
108+
109+
int main(int argc, char *argv[]) try {
110+
dpct::device_ext &dev_ct1 = dpct::get_current_device();
111+
112+
dpct::queue_ptr stream = &dpct::get_default_queue();
113+
dpct::rng::host_rng_ptr gen = NULL;
114+
dpct::rng::random_engine_type rng = dpct::rng::random_engine_type::mrg32k3a;
115+
curandOrdering_t order = CURAND_ORDERING_PSEUDO_BEST;
116+
117+
const int n = 10;
118+
119+
const unsigned long long offset = 0ULL;
120+
const unsigned long long seed = 1234ULL;
121+
122+
const data_type mean = 1.0f;
123+
const data_type stddev = 2.0f;
124+
125+
/* Create stream */
126+
/*
127+
DPCT1025:4: The SYCL queue is created ignoring the flag and priority options.
128+
*/
129+
CUDA_CHECK(DPCT_CHECK_ERROR(stream = dev_ct1.create_queue()));
130+
131+
/* Allocate n floats on host */
132+
std::vector<data_type> h_data(n, 0);
133+
134+
run_on_host(n, mean, stddev, offset, seed, order, rng, stream, gen, h_data);
135+
136+
printf("Host\n");
137+
print_vector(h_data);
138+
printf("=====\n");
139+
140+
run_on_device(n, mean, stddev, offset, seed, order, rng, stream, gen, h_data);
141+
142+
printf("Device\n");
143+
print_vector(h_data);
144+
printf("=====\n");
145+
146+
/* Cleanup */
147+
CURAND_CHECK(DPCT_CHECK_ERROR(gen.reset()));
148+
149+
CUDA_CHECK(DPCT_CHECK_ERROR(dev_ct1.destroy_queue(stream)));
150+
151+
CUDA_CHECK(DPCT_CHECK_ERROR(dev_ct1.reset()));
152+
153+
return EXIT_SUCCESS;
154+
}
155+
catch (sycl::exception const &exc) {
156+
std::cerr << exc.what() << "Exception caught at file:" << __FILE__
157+
<< ", line:" << __LINE__ << std::endl;
158+
std::exit(1);
159+
}

0 commit comments

Comments
 (0)