1 // Copyright 2013 Yangqing Jia
3 #include <cstdio>
4 #include <ctime>
6 #include "caffe/common.hpp"
8 namespace caffe {
10 shared_ptr<Caffe> Caffe::singleton_;
12 inline bool StillFresh() {
13 struct tm fresh_time;
14 fresh_time.tm_year = 200;
15 fresh_time.tm_mon = 1;
16 fresh_time.tm_mday = 1;
17 fresh_time.tm_hour = 0;
18 fresh_time.tm_min = 0;
19 fresh_time.tm_sec = 0;
20 return (difftime(time(NULL), mktime(&fresh_time)) < 0);
21 }
23 Caffe::Caffe()
24 : mode_(Caffe::CPU), phase_(Caffe::TRAIN), cublas_handle_(NULL),
25 curand_generator_(NULL), vsl_stream_(NULL) {
26 // A simple way to set an expire time - not for coding geeks, but meh.
27 // It simply works by skipping creating the streams.
28 if (!StillFresh()) {
29 return;
30 }
31 // Try to create a cublas handler, and report an error if failed (but we will
32 // keep the program running as one might just want to run CPU code).
33 if (cublasCreate(&cublas_handle_) != CUBLAS_STATUS_SUCCESS) {
34 LOG(ERROR) << "Cannot create Cublas handle. Cublas won't be available.";
35 }
36 // Try to create a curand handler.
37 if (curandCreateGenerator(&curand_generator_, CURAND_RNG_PSEUDO_DEFAULT)
38 != CURAND_STATUS_SUCCESS ||
39 curandSetPseudoRandomGeneratorSeed(curand_generator_, 1701ULL)
40 != CURAND_STATUS_SUCCESS) {
41 LOG(ERROR) << "Cannot create Curand generator. Curand won't be available.";
42 }
43 // Try to create a vsl stream. This should almost always work, but we will
44 // check it anyway.
45 if (vslNewStream(&vsl_stream_, VSL_BRNG_MT19937, 1701) != VSL_STATUS_OK) {
46 LOG(ERROR) << "Cannot create vsl stream. VSL random number generator "
47 << "won't be available.";
48 }
49 }
51 Caffe::~Caffe() {
52 if (cublas_handle_) CUBLAS_CHECK(cublasDestroy(cublas_handle_));
53 if (curand_generator_) {
54 CURAND_CHECK(curandDestroyGenerator(curand_generator_));
55 }
56 if (vsl_stream_) VSL_CHECK(vslDeleteStream(&vsl_stream_));
57 };
59 void Caffe::set_random_seed(const unsigned int seed) {
60 // Curand seed
61 // Yangqing's note: simply setting the generator seed does not seem to
62 // work on the tesla K20s, so I wrote the ugly reset thing below.
63 if (Get().curand_generator_) {
64 CURAND_CHECK(curandDestroyGenerator(curand_generator()));
65 CURAND_CHECK(curandCreateGenerator(&Get().curand_generator_,
66 CURAND_RNG_PSEUDO_DEFAULT));
67 CURAND_CHECK(curandSetPseudoRandomGeneratorSeed(curand_generator(),
68 seed));
69 } else {
70 LOG(ERROR) << "Curand not available. Skipping setting the curand seed.";
71 }
72 // VSL seed
73 VSL_CHECK(vslDeleteStream(&(Get().vsl_stream_)));
74 VSL_CHECK(vslNewStream(&(Get().vsl_stream_), VSL_BRNG_MT19937, seed));
75 }
77 void Caffe::DeviceQuery() {
78 cudaDeviceProp prop;
79 int device;
80 if (cudaSuccess != cudaGetDevice(&device)) {
81 printf("No cuda device present.\n");
82 return;
83 }
84 CUDA_CHECK(cudaGetDeviceProperties(&prop, device));
85 printf("Major revision number: %d\n", prop.major);
86 printf("Minor revision number: %d\n", prop.minor);
87 printf("Name: %s\n", prop.name);
88 printf("Total global memory: %lu\n", prop.totalGlobalMem);
89 printf("Total shared memory per block: %lu\n", prop.sharedMemPerBlock);
90 printf("Total registers per block: %d\n", prop.regsPerBlock);
91 printf("Warp size: %d\n", prop.warpSize);
92 printf("Maximum memory pitch: %lu\n", prop.memPitch);
93 printf("Maximum threads per block: %d\n", prop.maxThreadsPerBlock);
94 printf("Maximum dimension of block: %d, %d, %d\n",
95 prop.maxThreadsDim[0], prop.maxThreadsDim[1], prop.maxThreadsDim[2]);
96 printf("Maximum dimension of grid: %d, %d, %d\n",
97 prop.maxGridSize[0], prop.maxGridSize[1], prop.maxGridSize[2]);
98 printf("Clock rate: %d\n", prop.clockRate);
99 printf("Total constant memory: %lu\n", prop.totalConstMem);
100 printf("Texture alignment: %lu\n", prop.textureAlignment);
101 printf("Concurrent copy and execution: %s\n",
102 (prop.deviceOverlap ? "Yes" : "No"));
103 printf("Number of multiprocessors: %d\n", prop.multiProcessorCount);
104 printf("Kernel execution timeout: %s\n",
105 (prop.kernelExecTimeoutEnabled ? "Yes" : "No"));
106 return;
107 }
109 } // namespace caffe