1 // Copyright 2013 Yangqing Jia
3 #include <ctime>
5 #include "caffe/common.hpp"
7 namespace caffe {
9 shared_ptr<Caffe> Caffe::singleton_;
11 inline bool StillFresh() {
12 struct tm fresh_time;
13 fresh_time.tm_year = 200;
14 fresh_time.tm_mon = 1;
15 fresh_time.tm_mday = 1;
16 fresh_time.tm_hour = 0;
17 fresh_time.tm_min = 0;
18 fresh_time.tm_sec = 0;
19 return (difftime(time(NULL), mktime(&fresh_time)) < 0);
20 }
22 Caffe::Caffe()
23 : mode_(Caffe::CPU), phase_(Caffe::TRAIN), cublas_handle_(NULL),
24 curand_generator_(NULL), vsl_stream_(NULL) {
25 // A simple way to set an expire time - not for coding geeks, but meh.
26 // It simply works by skipping creating the streams.
27 if (!StillFresh()) {
28 return;
29 }
30 // Try to create a cublas handler, and report an error if failed (but we will
31 // keep the program running as one might just want to run CPU code).
32 if (cublasCreate(&cublas_handle_) != CUBLAS_STATUS_SUCCESS) {
33 LOG(ERROR) << "Cannot create Cublas handle. Cublas won't be available.";
34 }
35 // Try to create a curand handler.
36 if (curandCreateGenerator(&curand_generator_, CURAND_RNG_PSEUDO_DEFAULT)
37 != CURAND_STATUS_SUCCESS ||
38 curandSetPseudoRandomGeneratorSeed(curand_generator_, 1701ULL)
39 != CURAND_STATUS_SUCCESS) {
40 LOG(ERROR) << "Cannot create Curand generator. Curand won't be available.";
41 }
42 // Try to create a vsl stream. This should almost always work, but we will
43 // check it anyway.
44 if (vslNewStream(&vsl_stream_, VSL_BRNG_MT19937, 1701) != VSL_STATUS_OK) {
45 LOG(ERROR) << "Cannot create vsl stream. VSL random number generator "
46 << "won't be available.";
47 }
48 }
50 Caffe::~Caffe() {
51 if (!cublas_handle_) CUBLAS_CHECK(cublasDestroy(cublas_handle_));
52 if (!curand_generator_) {
53 CURAND_CHECK(curandDestroyGenerator(curand_generator_));
54 }
55 if (!vsl_stream_) VSL_CHECK(vslDeleteStream(&vsl_stream_));
56 };
58 void Caffe::set_random_seed(const unsigned int seed) {
59 // Curand seed
60 // Yangqing's note: simply setting the generator seed does not seem to
61 // work on the tesla K20s, so I wrote the ugly reset thing below.
62 if (Get().curand_generator_) {
63 CURAND_CHECK(curandDestroyGenerator(curand_generator()));
64 CURAND_CHECK(curandCreateGenerator(&Get().curand_generator_,
65 CURAND_RNG_PSEUDO_DEFAULT));
66 CURAND_CHECK(curandSetPseudoRandomGeneratorSeed(curand_generator(),
67 seed));
68 } else {
69 LOG(ERROR) << "Curand not available. Skipping setting the curand seed.";
70 }
71 // VSL seed
72 VSL_CHECK(vslDeleteStream(&(Get().vsl_stream_)));
73 VSL_CHECK(vslNewStream(&(Get().vsl_stream_), VSL_BRNG_MT19937, seed));
74 }
76 } // namespace caffe