common: added DeviceQuery() function
[jacinto-ai/caffe-jacinto.git] / src / caffe / common.cpp
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   CUDA_CHECK(cudaGetDevice(&device));
81   CUDA_CHECK(cudaGetDeviceProperties(&prop, device));
82   printf("Major revision number:         %d\n", prop.major);
83   printf("Minor revision number:         %d\n", prop.minor);
84   printf("Name:                          %s\n", prop.name);
85   printf("Total global memory:           %lu\n", prop.totalGlobalMem);
86   printf("Total shared memory per block: %lu\n", prop.sharedMemPerBlock);
87   printf("Total registers per block:     %d\n", prop.regsPerBlock);
88   printf("Warp size:                     %d\n", prop.warpSize);
89   printf("Maximum memory pitch:          %lu\n", prop.memPitch);
90   printf("Maximum threads per block:     %d\n", prop.maxThreadsPerBlock);
91   printf("Maximum dimension of block:    %d, %d, %d\n",
92       prop.maxThreadsDim[0], prop.maxThreadsDim[1], prop.maxThreadsDim[2]);
93   printf("Maximum dimension of grid:     %d, %d, %d\n",
94       prop.maxGridSize[0], prop.maxGridSize[1], prop.maxGridSize[2]);
95   printf("Clock rate:                    %d\n", prop.clockRate);
96   printf("Total constant memory:         %lu\n", prop.totalConstMem);
97   printf("Texture alignment:             %lu\n", prop.textureAlignment);
98   printf("Concurrent copy and execution: %s\n",
99       (prop.deviceOverlap ? "Yes" : "No"));
100   printf("Number of multiprocessors:     %d\n", prop.multiProcessorCount);
101   printf("Kernel execution timeout:      %s\n",
102       (prop.kernelExecTimeoutEnabled ? "Yes" : "No"));
103   return;
106 }  // namespace caffe