[TREE] Move the files to target refactor location
This commit is contained in:
parent
3128e1705b
commit
4adc4cf0b9
@ -1,42 +0,0 @@
|
||||
/*!
|
||||
* Copyright 2014 by Contributors
|
||||
* \file iterator.h
|
||||
* \brief itertator interface
|
||||
* \author Tianqi Chen
|
||||
*/
|
||||
#ifndef XGBOOST_UTILS_ITERATOR_H_
|
||||
#define XGBOOST_UTILS_ITERATOR_H_
|
||||
#include <cstdio>
|
||||
|
||||
namespace xgboost {
|
||||
namespace utils {
|
||||
/*!
|
||||
* \brief iterator interface
|
||||
* \tparam DType data type
|
||||
*/
|
||||
template<typename DType>
|
||||
class IIterator {
|
||||
public:
|
||||
/*!
|
||||
* \brief set the parameter
|
||||
* \param name name of parameter
|
||||
* \param val value of parameter
|
||||
*/
|
||||
virtual void SetParam(const char *name, const char *val) {}
|
||||
/*! \brief initialize the iterator so that we can use the iterator */
|
||||
virtual void Init(void) {}
|
||||
/*! \brief set before first of the item */
|
||||
virtual void BeforeFirst(void) = 0;
|
||||
/*! \brief move to next item */
|
||||
virtual bool Next(void) = 0;
|
||||
/*! \brief get current data */
|
||||
virtual const DType &Value(void) const = 0;
|
||||
public:
|
||||
/*! \brief constructor */
|
||||
virtual ~IIterator(void) {}
|
||||
};
|
||||
|
||||
} // namespace utils
|
||||
} // namespace xgboost
|
||||
#endif // XGBOOST_UTILS_ITERATOR_H_
|
||||
|
||||
@ -1,34 +0,0 @@
|
||||
/*!
|
||||
* Copyright 2014 by Contributors
|
||||
* \file omp.h
|
||||
* \brief header to handle OpenMP compatibility issues
|
||||
* \author Tianqi Chen
|
||||
*/
|
||||
#ifndef XGBOOST_UTILS_OMP_H_
|
||||
#define XGBOOST_UTILS_OMP_H_
|
||||
|
||||
#if defined(_OPENMP) && !defined(DISABLE_OPENMP)
|
||||
#include <omp.h>
|
||||
#else
|
||||
#if !defined(DISABLE_OPENMP) && !defined(_MSC_VER)
|
||||
// use pragma message instead of warning
|
||||
#pragma message("Warning: OpenMP is not available,"\
|
||||
"xgboost will be compiled into single-thread code."\
|
||||
"Use OpenMP-enabled compiler to get benefit of multi-threading")
|
||||
#endif
|
||||
inline int omp_get_thread_num() { return 0; }
|
||||
inline int omp_get_num_threads() { return 1; }
|
||||
inline void omp_set_num_threads(int nthread) {}
|
||||
inline int omp_get_num_procs() { return 1; }
|
||||
#endif
|
||||
|
||||
// loop variable used in openmp
|
||||
namespace xgboost {
|
||||
#ifdef _MSC_VER
|
||||
typedef int bst_omp_uint;
|
||||
#else
|
||||
typedef unsigned bst_omp_uint;
|
||||
#endif
|
||||
} // namespace xgboost
|
||||
|
||||
#endif // XGBOOST_UTILS_OMP_H_
|
||||
@ -1,108 +0,0 @@
|
||||
/*!
|
||||
* Copyright 2014 by Contributors
|
||||
* \file xgboost_random.h
|
||||
* \brief PRNG to support random number generation
|
||||
* \author Tianqi Chen: tianqi.tchen@gmail.com
|
||||
*
|
||||
* Use standard PRNG from stdlib
|
||||
*/
|
||||
#ifndef XGBOOST_UTILS_RANDOM_H_
|
||||
#define XGBOOST_UTILS_RANDOM_H_
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include "./utils.h"
|
||||
|
||||
/*! namespace of PRNG */
|
||||
namespace xgboost {
|
||||
namespace random {
|
||||
#ifndef XGBOOST_CUSTOMIZE_PRNG_
|
||||
/*! \brief seed the PRNG */
|
||||
inline void Seed(unsigned seed) {
|
||||
srand(seed);
|
||||
}
|
||||
/*! \brief basic function, uniform */
|
||||
inline double Uniform(void) {
|
||||
return static_cast<double>(rand()) / (static_cast<double>(RAND_MAX)+1.0); // NOLINT(*)
|
||||
}
|
||||
/*! \brief return a real number uniform in (0,1) */
|
||||
inline double NextDouble2(void) {
|
||||
return (static_cast<double>(rand()) + 1.0) / (static_cast<double>(RAND_MAX)+2.0); // NOLINT(*)
|
||||
}
|
||||
/*! \brief return x~N(0,1) */
|
||||
inline double Normal(void) {
|
||||
double x, y, s;
|
||||
do {
|
||||
x = 2 * NextDouble2() - 1.0;
|
||||
y = 2 * NextDouble2() - 1.0;
|
||||
s = x*x + y*y;
|
||||
} while (s >= 1.0 || s == 0.0);
|
||||
|
||||
return x * sqrt(-2.0 * log(s) / s);
|
||||
}
|
||||
#else
|
||||
// include declarations, to be implemented
|
||||
void Seed(unsigned seed);
|
||||
double Uniform(void);
|
||||
double Normal(void);
|
||||
#endif
|
||||
|
||||
/*! \brief return a real number uniform in [0,1) */
|
||||
inline double NextDouble(void) {
|
||||
return Uniform();
|
||||
}
|
||||
/*! \brief return a random number in n */
|
||||
inline uint32_t NextUInt32(uint32_t n) {
|
||||
return (uint32_t)std::floor(NextDouble() * n);
|
||||
}
|
||||
/*! \brief return x~N(mu,sigma^2) */
|
||||
inline double SampleNormal(double mu, double sigma) {
|
||||
return Normal() * sigma + mu;
|
||||
}
|
||||
/*! \brief return 1 with probability p, coin flip */
|
||||
inline int SampleBinary(double p) {
|
||||
return NextDouble() < p;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void Shuffle(T *data, size_t sz) {
|
||||
if (sz == 0) return;
|
||||
for (uint32_t i = (uint32_t)sz - 1; i > 0; i--) {
|
||||
std::swap(data[i], data[NextUInt32(i + 1)]);
|
||||
}
|
||||
}
|
||||
// random shuffle the data inside, require PRNG
|
||||
template<typename T>
|
||||
inline void Shuffle(std::vector<T> &data) { // NOLINT(*)
|
||||
Shuffle(&data[0], data.size());
|
||||
}
|
||||
|
||||
/*! \brief random number generator with independent random number seed*/
|
||||
struct Random{
|
||||
/*! \brief set random number seed */
|
||||
inline void Seed(unsigned sd) {
|
||||
this->rseed = sd;
|
||||
#if defined(_MSC_VER) || defined(_WIN32)
|
||||
::xgboost::random::Seed(sd);
|
||||
#endif
|
||||
}
|
||||
/*! \brief return a real number uniform in [0,1) */
|
||||
inline double RandDouble(void) {
|
||||
// use rand instead of rand_r in windows, for MSVC it is fine since rand is threadsafe
|
||||
// For cygwin and mingw, this can slows down parallelism,
|
||||
// but rand_r is only used in objective-inl.hpp, won't affect speed in general
|
||||
// todo, replace with another PRNG
|
||||
#if defined(_MSC_VER) || defined(_WIN32) || defined(XGBOOST_STRICT_CXX98_)
|
||||
return Uniform();
|
||||
#else
|
||||
return static_cast<double>(rand_r(&rseed)) / (static_cast<double>(RAND_MAX) + 1.0);
|
||||
#endif
|
||||
}
|
||||
// random number seed
|
||||
unsigned rseed;
|
||||
};
|
||||
} // namespace random
|
||||
} // namespace xgboost
|
||||
#endif // XGBOOST_UTILS_RANDOM_H_
|
||||
@ -1,260 +0,0 @@
|
||||
/*!
|
||||
* Copyright by Contributors
|
||||
* \file thread.h
|
||||
* \brief this header include the minimum necessary resource
|
||||
* for multi-threading that can be compiled in windows, linux, mac
|
||||
* \author Tianqi Chen
|
||||
*/
|
||||
#ifndef XGBOOST_UTILS_THREAD_H_ // NOLINT(*)
|
||||
#define XGBOOST_UTILS_THREAD_H_ // NOLINT(*)
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <windows.h>
|
||||
#include <process.h>
|
||||
#include "./utils.h"
|
||||
namespace xgboost {
|
||||
namespace utils {
|
||||
/*! \brief simple semaphore used for synchronization */
|
||||
class Semaphore {
|
||||
public :
|
||||
inline void Init(int init_val) {
|
||||
sem = CreateSemaphore(NULL, init_val, 10, NULL);
|
||||
utils::Check(sem != NULL, "create Semaphore error");
|
||||
}
|
||||
inline void Destroy(void) {
|
||||
CloseHandle(sem);
|
||||
}
|
||||
inline void Wait(void) {
|
||||
utils::Check(WaitForSingleObject(sem, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject error");
|
||||
}
|
||||
inline void Post(void) {
|
||||
utils::Check(ReleaseSemaphore(sem, 1, NULL) != 0, "ReleaseSemaphore error");
|
||||
}
|
||||
|
||||
private:
|
||||
HANDLE sem;
|
||||
};
|
||||
|
||||
/*! \brief mutex under windows */
|
||||
class Mutex {
|
||||
public:
|
||||
inline void Init(void) {
|
||||
utils::Check(InitializeCriticalSectionAndSpinCount(&mutex, 0x00000400) != 0,
|
||||
"Mutex::Init fail");
|
||||
}
|
||||
inline void Lock(void) {
|
||||
EnterCriticalSection(&mutex);
|
||||
}
|
||||
inline void Unlock(void) {
|
||||
LeaveCriticalSection(&mutex);
|
||||
}
|
||||
inline void Destroy(void) {
|
||||
DeleteCriticalSection(&mutex);
|
||||
}
|
||||
|
||||
private:
|
||||
friend class ConditionVariable;
|
||||
CRITICAL_SECTION mutex;
|
||||
};
|
||||
|
||||
// conditional variable that uses pthread
|
||||
class ConditionVariable {
|
||||
public:
|
||||
// initialize conditional variable
|
||||
inline void Init(void) {
|
||||
InitializeConditionVariable(&cond);
|
||||
}
|
||||
// destroy the thread
|
||||
inline void Destroy(void) {
|
||||
// DeleteConditionVariable(&cond);
|
||||
}
|
||||
// wait on the conditional variable
|
||||
inline void Wait(Mutex *mutex) {
|
||||
utils::Check(SleepConditionVariableCS(&cond, &(mutex->mutex), INFINITE) != 0,
|
||||
"ConditionVariable:Wait fail");
|
||||
}
|
||||
inline void Broadcast(void) {
|
||||
WakeAllConditionVariable(&cond);
|
||||
}
|
||||
inline void Signal(void) {
|
||||
WakeConditionVariable(&cond);
|
||||
}
|
||||
|
||||
private:
|
||||
CONDITION_VARIABLE cond;
|
||||
};
|
||||
|
||||
/*! \brief simple thread that wraps windows thread */
|
||||
class Thread {
|
||||
private:
|
||||
HANDLE thread_handle;
|
||||
unsigned thread_id;
|
||||
public:
|
||||
inline void Start(unsigned int __stdcall entry(void*p), void *param) {
|
||||
thread_handle = (HANDLE)_beginthreadex(NULL, 0, entry, param, 0, &thread_id);
|
||||
}
|
||||
inline int Join(void) {
|
||||
WaitForSingleObject(thread_handle, INFINITE);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
/*! \brief exit function called from thread */
|
||||
inline void ThreadExit(void *status) {
|
||||
_endthreadex(0);
|
||||
}
|
||||
#define XGBOOST_THREAD_PREFIX unsigned int __stdcall
|
||||
} // namespace utils
|
||||
} // namespace xgboost
|
||||
#else
|
||||
// thread interface using g++
|
||||
#include <semaphore.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
namespace xgboost {
|
||||
namespace utils {
|
||||
/*!\brief semaphore class */
|
||||
class Semaphore {
|
||||
#ifdef __APPLE__
|
||||
|
||||
private:
|
||||
sem_t* semPtr;
|
||||
char sema_name[20];
|
||||
|
||||
private:
|
||||
inline void GenRandomString(char *s, const int len) {
|
||||
static const char alphanum[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
for (int i = 0; i < len; ++i) {
|
||||
s[i] = alphanum[rand() % (sizeof(alphanum) - 1)];
|
||||
}
|
||||
s[len] = 0;
|
||||
}
|
||||
|
||||
public:
|
||||
inline void Init(int init_val) {
|
||||
sema_name[0] = '/';
|
||||
sema_name[1] = 's';
|
||||
sema_name[2] = 'e';
|
||||
sema_name[3] = '/';
|
||||
GenRandomString(&sema_name[4], 16);
|
||||
if ((semPtr = sem_open(sema_name, O_CREAT, 0644, init_val)) == SEM_FAILED) {
|
||||
perror("sem_open");
|
||||
exit(1);
|
||||
}
|
||||
utils::Check(semPtr != NULL, "create Semaphore error");
|
||||
}
|
||||
inline void Destroy(void) {
|
||||
if (sem_close(semPtr) == -1) {
|
||||
perror("sem_close");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (sem_unlink(sema_name) == -1) {
|
||||
perror("sem_unlink");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
inline void Wait(void) {
|
||||
sem_wait(semPtr);
|
||||
}
|
||||
inline void Post(void) {
|
||||
sem_post(semPtr);
|
||||
}
|
||||
#else
|
||||
|
||||
private:
|
||||
sem_t sem;
|
||||
|
||||
public:
|
||||
inline void Init(int init_val) {
|
||||
if (sem_init(&sem, 0, init_val) != 0) {
|
||||
utils::Error("Semaphore.Init:%s", strerror(errno));
|
||||
}
|
||||
}
|
||||
inline void Destroy(void) {
|
||||
if (sem_destroy(&sem) != 0) {
|
||||
utils::Error("Semaphore.Destroy:%s", strerror(errno));
|
||||
}
|
||||
}
|
||||
inline void Wait(void) {
|
||||
if (sem_wait(&sem) != 0) {
|
||||
utils::Error("Semaphore.Wait:%s", strerror(errno));
|
||||
}
|
||||
}
|
||||
inline void Post(void) {
|
||||
if (sem_post(&sem) != 0) {
|
||||
utils::Error("Semaphore.Post:%s", strerror(errno));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
// mutex that works with pthread
|
||||
class Mutex {
|
||||
public:
|
||||
inline void Init(void) {
|
||||
pthread_mutex_init(&mutex, NULL);
|
||||
}
|
||||
inline void Lock(void) {
|
||||
pthread_mutex_lock(&mutex);
|
||||
}
|
||||
inline void Unlock(void) {
|
||||
pthread_mutex_unlock(&mutex);
|
||||
}
|
||||
inline void Destroy(void) {
|
||||
pthread_mutex_destroy(&mutex);
|
||||
}
|
||||
|
||||
private:
|
||||
friend class ConditionVariable;
|
||||
pthread_mutex_t mutex;
|
||||
};
|
||||
|
||||
// conditional variable that uses pthread
|
||||
class ConditionVariable {
|
||||
public:
|
||||
// initialize conditional variable
|
||||
inline void Init(void) {
|
||||
pthread_cond_init(&cond, NULL);
|
||||
}
|
||||
// destroy the thread
|
||||
inline void Destroy(void) {
|
||||
pthread_cond_destroy(&cond);
|
||||
}
|
||||
// wait on the conditional variable
|
||||
inline void Wait(Mutex *mutex) {
|
||||
pthread_cond_wait(&cond, &(mutex->mutex));
|
||||
}
|
||||
inline void Broadcast(void) {
|
||||
pthread_cond_broadcast(&cond);
|
||||
}
|
||||
inline void Signal(void) {
|
||||
pthread_cond_signal(&cond);
|
||||
}
|
||||
|
||||
private:
|
||||
pthread_cond_t cond;
|
||||
};
|
||||
|
||||
/*!\brief simple thread class */
|
||||
class Thread {
|
||||
private:
|
||||
pthread_t thread;
|
||||
public :
|
||||
inline void Start(void * entry(void*), void *param) { // NOLINT(*)
|
||||
pthread_attr_t attr;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
|
||||
pthread_create(&thread, &attr, entry, param);
|
||||
}
|
||||
inline int Join(void) {
|
||||
void *status;
|
||||
return pthread_join(thread, &status);
|
||||
}
|
||||
};
|
||||
inline void ThreadExit(void *status) {
|
||||
pthread_exit(status);
|
||||
}
|
||||
} // namespace utils
|
||||
} // namespace xgboost
|
||||
#define XGBOOST_THREAD_PREFIX void *
|
||||
#endif // Linux
|
||||
#endif // XGBOOST_UTILS_THREAD_H_ NOLINT(*)
|
||||
@ -1,257 +0,0 @@
|
||||
/*!
|
||||
* Copyright 2014 by Contributors
|
||||
* \file thread_buffer.h
|
||||
* \brief multi-thread buffer, iterator, can be used to create parallel pipeline
|
||||
* \author Tianqi Chen
|
||||
*/
|
||||
#ifndef XGBOOST_UTILS_THREAD_BUFFER_H_
|
||||
#define XGBOOST_UTILS_THREAD_BUFFER_H_
|
||||
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include "./utils.h"
|
||||
// threading util could not run on solaris
|
||||
#ifndef XGBOOST_STRICT_CXX98_
|
||||
#include "./thread.h"
|
||||
#endif
|
||||
|
||||
namespace xgboost {
|
||||
namespace utils {
|
||||
#if !defined(XGBOOST_STRICT_CXX98_)
|
||||
/*!
|
||||
* \brief buffered loading iterator that uses multithread
|
||||
* this template method will assume the following parameters
|
||||
* \tparam Elem element type to be buffered
|
||||
* \tparam ElemFactory factory type to implement in order to use thread buffer
|
||||
*/
|
||||
template<typename Elem, typename ElemFactory>
|
||||
class ThreadBuffer {
|
||||
public:
|
||||
/*!\brief constructor */
|
||||
ThreadBuffer(void) {
|
||||
this->init_end = false;
|
||||
this->buf_size = 30;
|
||||
}
|
||||
~ThreadBuffer(void) {
|
||||
if (init_end) this->Destroy();
|
||||
}
|
||||
/*!\brief set parameter, will also pass the parameter to factory */
|
||||
inline void SetParam(const char *name, const char *val) {
|
||||
using namespace std;
|
||||
if (!strcmp( name, "buffer_size")) buf_size = atoi(val);
|
||||
factory.SetParam(name, val);
|
||||
}
|
||||
/*!
|
||||
* \brief initalize the buffered iterator
|
||||
* \param param a initialize parameter that will pass to factory, ignore it if not necessary
|
||||
* \return false if the initialization can't be done, e.g. buffer file hasn't been created
|
||||
*/
|
||||
inline bool Init(void) {
|
||||
if (!factory.Init()) return false;
|
||||
for (int i = 0; i < buf_size; ++i) {
|
||||
bufA.push_back(factory.Create());
|
||||
bufB.push_back(factory.Create());
|
||||
}
|
||||
this->init_end = true;
|
||||
this->StartLoader();
|
||||
return true;
|
||||
}
|
||||
/*!\brief place the iterator before first value */
|
||||
inline void BeforeFirst(void) {
|
||||
// wait till last loader end
|
||||
loading_end.Wait();
|
||||
// critical zone
|
||||
current_buf = 1;
|
||||
factory.BeforeFirst();
|
||||
// reset terminate limit
|
||||
endA = endB = buf_size;
|
||||
// wake up loader for first part
|
||||
loading_need.Post();
|
||||
// wait til first part is loaded
|
||||
loading_end.Wait();
|
||||
// set current buf to right value
|
||||
current_buf = 0;
|
||||
// wake loader for next part
|
||||
data_loaded = false;
|
||||
loading_need.Post();
|
||||
// set buffer value
|
||||
buf_index = 0;
|
||||
}
|
||||
/*! \brief destroy the buffer iterator, will deallocate the buffer */
|
||||
inline void Destroy(void) {
|
||||
// wait until the signal is consumed
|
||||
this->destroy_signal = true;
|
||||
loading_need.Post();
|
||||
loader_thread.Join();
|
||||
loading_need.Destroy();
|
||||
loading_end.Destroy();
|
||||
for (size_t i = 0; i < bufA.size(); ++i) {
|
||||
factory.FreeSpace(bufA[i]);
|
||||
}
|
||||
for (size_t i = 0; i < bufB.size(); ++i) {
|
||||
factory.FreeSpace(bufB[i]);
|
||||
}
|
||||
bufA.clear(); bufB.clear();
|
||||
factory.Destroy();
|
||||
this->init_end = false;
|
||||
}
|
||||
/*!
|
||||
* \brief get the next element needed in buffer
|
||||
* \param elem element to store into
|
||||
* \return whether reaches end of data
|
||||
*/
|
||||
inline bool Next(Elem &elem) { // NOLINT(*)
|
||||
// end of buffer try to switch
|
||||
if (buf_index == buf_size) {
|
||||
this->SwitchBuffer();
|
||||
buf_index = 0;
|
||||
}
|
||||
if (buf_index >= (current_buf ? endA : endB)) {
|
||||
return false;
|
||||
}
|
||||
std::vector<Elem> &buf = current_buf ? bufA : bufB;
|
||||
elem = buf[buf_index];
|
||||
++buf_index;
|
||||
return true;
|
||||
}
|
||||
/*!
|
||||
* \brief get the factory object
|
||||
*/
|
||||
inline ElemFactory &get_factory(void) {
|
||||
return factory;
|
||||
}
|
||||
inline const ElemFactory &get_factory(void) const {
|
||||
return factory;
|
||||
}
|
||||
// size of buffer
|
||||
int buf_size;
|
||||
|
||||
private:
|
||||
// factory object used to load configures
|
||||
ElemFactory factory;
|
||||
// index in current buffer
|
||||
int buf_index;
|
||||
// indicate which one is current buffer
|
||||
int current_buf;
|
||||
// max limit of visit, also marks termination
|
||||
int endA, endB;
|
||||
// double buffer, one is accessed by loader
|
||||
// the other is accessed by consumer
|
||||
// buffer of the data
|
||||
std::vector<Elem> bufA, bufB;
|
||||
// initialization end
|
||||
bool init_end;
|
||||
// singal whether the data is loaded
|
||||
bool data_loaded;
|
||||
// signal to kill the thread
|
||||
bool destroy_signal;
|
||||
// thread object
|
||||
Thread loader_thread;
|
||||
// signal of the buffer
|
||||
Semaphore loading_end, loading_need;
|
||||
/*!
|
||||
* \brief slave thread
|
||||
* this implementation is like producer-consumer style
|
||||
*/
|
||||
inline void RunLoader(void) {
|
||||
while (!destroy_signal) {
|
||||
// sleep until loading is needed
|
||||
loading_need.Wait();
|
||||
std::vector<Elem> &buf = current_buf ? bufB : bufA;
|
||||
int i;
|
||||
for (i = 0; i < buf_size ; ++i) {
|
||||
if (!factory.LoadNext(buf[i])) {
|
||||
int &end = current_buf ? endB : endA;
|
||||
end = i; // marks the termination
|
||||
break;
|
||||
}
|
||||
}
|
||||
// signal that loading is done
|
||||
data_loaded = true;
|
||||
loading_end.Post();
|
||||
}
|
||||
}
|
||||
/*!\brief entry point of loader thread */
|
||||
inline static XGBOOST_THREAD_PREFIX LoaderEntry(void *pthread) {
|
||||
static_cast< ThreadBuffer<Elem, ElemFactory>* >(pthread)->RunLoader();
|
||||
return NULL;
|
||||
}
|
||||
/*!\brief start loader thread */
|
||||
inline void StartLoader(void) {
|
||||
destroy_signal = false;
|
||||
// set param
|
||||
current_buf = 1;
|
||||
loading_need.Init(1);
|
||||
loading_end .Init(0);
|
||||
// reset terminate limit
|
||||
endA = endB = buf_size;
|
||||
loader_thread.Start(LoaderEntry, this);
|
||||
// wait until first part of data is loaded
|
||||
loading_end.Wait();
|
||||
// set current buf to right value
|
||||
current_buf = 0;
|
||||
// wake loader for next part
|
||||
data_loaded = false;
|
||||
loading_need.Post();
|
||||
buf_index = 0;
|
||||
}
|
||||
/*!\brief switch double buffer */
|
||||
inline void SwitchBuffer(void) {
|
||||
loading_end.Wait();
|
||||
// loader shall be sleep now, critcal zone!
|
||||
current_buf = !current_buf;
|
||||
// wake up loader
|
||||
data_loaded = false;
|
||||
loading_need.Post();
|
||||
}
|
||||
};
|
||||
#else
|
||||
// a dummy single threaded ThreadBuffer
|
||||
// use this to resolve R's solaris compatibility for now
|
||||
template<typename Elem, typename ElemFactory>
|
||||
class ThreadBuffer {
|
||||
public:
|
||||
ThreadBuffer() : init_end_(false) {}
|
||||
~ThreadBuffer() {
|
||||
if (init_end_) {
|
||||
factory_.FreeSpace(data_);
|
||||
factory_.Destroy();
|
||||
}
|
||||
}
|
||||
inline void SetParam(const char *name, const char *val) {
|
||||
}
|
||||
inline bool Init(void) {
|
||||
if (!factory_.Init()) return false;
|
||||
data_ = factory_.Create();
|
||||
return (init_end_ = true);
|
||||
}
|
||||
inline void BeforeFirst(void) {
|
||||
factory_.BeforeFirst();
|
||||
}
|
||||
inline bool Next(Elem &elem) { // NOLINT(*)
|
||||
if (factory_.LoadNext(data_)) {
|
||||
elem = data_; return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
inline ElemFactory &get_factory() {
|
||||
return factory_;
|
||||
}
|
||||
inline const ElemFactory &get_factory() const {
|
||||
return factory_;
|
||||
}
|
||||
|
||||
private:
|
||||
// initialized
|
||||
bool init_end_;
|
||||
// current data
|
||||
Elem data_;
|
||||
// factory object used to load configures
|
||||
ElemFactory factory_;
|
||||
};
|
||||
#endif // !defined(XGBOOST_STRICT_CXX98_)
|
||||
} // namespace utils
|
||||
} // namespace xgboost
|
||||
#endif // XGBOOST_UTILS_THREAD_BUFFER_H_
|
||||
@ -1,188 +0,0 @@
|
||||
/*!
|
||||
* Copyright 2014 by Contributors
|
||||
* \file utils.h
|
||||
* \brief simple utils to support the code
|
||||
* \author Tianqi Chen
|
||||
*/
|
||||
#ifndef XGBOOST_UTILS_UTILS_H_
|
||||
#define XGBOOST_UTILS_UTILS_H_
|
||||
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
#include <cstdlib>
|
||||
#include <vector>
|
||||
#include <stdexcept>
|
||||
|
||||
#ifndef XGBOOST_STRICT_CXX98_
|
||||
#include <cstdarg>
|
||||
#endif
|
||||
|
||||
#if !defined(__GNUC__)
|
||||
#define fopen64 std::fopen
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
// NOTE: sprintf_s is not equivalent to snprintf,
|
||||
// they are equivalent when success, which is sufficient for our case
|
||||
#define snprintf sprintf_s
|
||||
#define vsnprintf vsprintf_s
|
||||
#else
|
||||
#ifdef _FILE_OFFSET_BITS
|
||||
#if _FILE_OFFSET_BITS == 32
|
||||
#pragma message("Warning: FILE OFFSET BITS defined to be 32 bit")
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#define off64_t off_t
|
||||
#define fopen64 std::fopen
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
#include <sys/types.h>
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
typedef __int64 int64_t;
|
||||
#else
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
namespace xgboost {
|
||||
/*! \brief namespace for helper utils of the project */
|
||||
namespace utils {
|
||||
|
||||
/*! \brief error message buffer length */
|
||||
const int kPrintBuffer = 1 << 12;
|
||||
|
||||
#ifndef XGBOOST_CUSTOMIZE_MSG_
|
||||
/*!
|
||||
* \brief handling of Assert error, caused by inappropriate input
|
||||
* \param msg error message
|
||||
*/
|
||||
inline void HandleAssertError(const char *msg) {
|
||||
fprintf(stderr, "AssertError:%s\n", msg);
|
||||
exit(-1);
|
||||
}
|
||||
/*!
|
||||
* \brief handling of Check error, caused by inappropriate input
|
||||
* \param msg error message
|
||||
*/
|
||||
inline void HandleCheckError(const char *msg) {
|
||||
throw std::runtime_error(msg);
|
||||
}
|
||||
inline void HandlePrint(const char *msg) {
|
||||
printf("%s", msg);
|
||||
}
|
||||
#else
|
||||
#ifndef XGBOOST_STRICT_CXX98_
|
||||
// include declarations, some one must implement this
|
||||
void HandleAssertError(const char *msg);
|
||||
void HandleCheckError(const char *msg);
|
||||
void HandlePrint(const char *msg);
|
||||
#endif
|
||||
#endif
|
||||
#ifdef XGBOOST_STRICT_CXX98_
|
||||
// these function pointers are to be assigned
|
||||
extern "C" void (*Printf)(const char *fmt, ...);
|
||||
extern "C" int (*SPrintf)(char *buf, size_t size, const char *fmt, ...);
|
||||
extern "C" void (*Assert)(int exp, const char *fmt, ...);
|
||||
extern "C" void (*Check)(int exp, const char *fmt, ...);
|
||||
extern "C" void (*Error)(const char *fmt, ...);
|
||||
#else
|
||||
/*! \brief printf, print message to the console */
|
||||
inline void Printf(const char *fmt, ...) {
|
||||
std::string msg(kPrintBuffer, '\0');
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsnprintf(&msg[0], kPrintBuffer, fmt, args);
|
||||
va_end(args);
|
||||
HandlePrint(msg.c_str());
|
||||
}
|
||||
/*! \brief portable version of snprintf */
|
||||
inline int SPrintf(char *buf, size_t size, const char *fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
int ret = vsnprintf(buf, size, fmt, args);
|
||||
va_end(args);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*! \brief assert an condition is true, use this to handle debug information */
|
||||
inline void Assert(bool exp, const char *fmt, ...) {
|
||||
if (!exp) {
|
||||
std::string msg(kPrintBuffer, '\0');
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsnprintf(&msg[0], kPrintBuffer, fmt, args);
|
||||
va_end(args);
|
||||
HandleAssertError(msg.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
/*!\brief same as assert, but this is intended to be used as message for user*/
|
||||
inline void Check(bool exp, const char *fmt, ...) {
|
||||
if (!exp) {
|
||||
std::string msg(kPrintBuffer, '\0');
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsnprintf(&msg[0], kPrintBuffer, fmt, args);
|
||||
va_end(args);
|
||||
HandleCheckError(msg.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
/*! \brief report error message, same as check */
|
||||
inline void Error(const char *fmt, ...) {
|
||||
{
|
||||
std::string msg(kPrintBuffer, '\0');
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsnprintf(&msg[0], kPrintBuffer, fmt, args);
|
||||
va_end(args);
|
||||
HandleCheckError(msg.c_str());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*! \brief replace fopen, report error when the file open fails */
|
||||
inline std::FILE *FopenCheck(const char *fname, const char *flag) {
|
||||
std::FILE *fp = fopen64(fname, flag);
|
||||
Check(fp != NULL, "can not open file \"%s\"\n", fname);
|
||||
return fp;
|
||||
}
|
||||
} // namespace utils
|
||||
// easy utils that can be directly accessed in xgboost
|
||||
/*! \brief get the beginning address of a vector */
|
||||
template<typename T>
|
||||
inline T *BeginPtr(std::vector<T> &vec) { // NOLINT(*)
|
||||
if (vec.size() == 0) {
|
||||
return NULL;
|
||||
} else {
|
||||
return &vec[0];
|
||||
}
|
||||
}
|
||||
/*! \brief get the beginning address of a vector */
|
||||
template<typename T>
|
||||
inline const T *BeginPtr(const std::vector<T> &vec) {
|
||||
if (vec.size() == 0) {
|
||||
return NULL;
|
||||
} else {
|
||||
return &vec[0];
|
||||
}
|
||||
}
|
||||
inline char* BeginPtr(std::string &str) { // NOLINT(*)
|
||||
if (str.length() == 0) return NULL;
|
||||
return &str[0];
|
||||
}
|
||||
inline const char* BeginPtr(const std::string &str) {
|
||||
if (str.length() == 0) return NULL;
|
||||
return &str[0];
|
||||
}
|
||||
} // namespace xgboost
|
||||
#endif // XGBOOST_UTILS_UTILS_H_
|
||||
Loading…
x
Reference in New Issue
Block a user