Squashed 'subtree/rabit/' changes from 1db6449..85b7463

85b7463 change def of reducer to take function ptr
fe6366e add engine base
a98720e more deps

git-subtree-dir: subtree/rabit
git-subtree-split: 85b746394e0bed36a22ebb12beb8672616b39047
This commit is contained in:
tqchen 2015-01-19 21:26:25 -08:00
parent 81749e6b63
commit ea50f8e030
10 changed files with 78 additions and 24 deletions

View File

@ -10,13 +10,13 @@ BPATH=.
# objectives that makes up rabit library # objectives that makes up rabit library
MPIOBJ= $(BPATH)/engine_mpi.o MPIOBJ= $(BPATH)/engine_mpi.o
OBJ= $(BPATH)/allreduce_base.o $(BPATH)/allreduce_robust.o $(BPATH)/engine.o $(BPATH)/engine_empty.o $(BPATH)/engine_mock.o\ OBJ= $(BPATH)/allreduce_base.o $(BPATH)/allreduce_robust.o $(BPATH)/engine.o $(BPATH)/engine_empty.o $(BPATH)/engine_mock.o\
$(BPATH)/rabit_wrapper.o $(BPATH)/rabit_wrapper.o $(BPATH)/engine_base.o
SLIB= wrapper/librabit_wrapper.so wrapper/librabit_wrapper_mock.so wrapper/librabit_wrapper_mpi.so SLIB= wrapper/librabit_wrapper.so wrapper/librabit_wrapper_mock.so wrapper/librabit_wrapper_mpi.so
ALIB= lib/librabit.a lib/librabit_mpi.a lib/librabit_empty.a lib/librabit_mock.a ALIB= lib/librabit.a lib/librabit_mpi.a lib/librabit_empty.a lib/librabit_mock.a lib/librabit_base.a
HEADERS=src/*.h include/*.h include/rabit/*.h HEADERS=src/*.h include/*.h include/rabit/*.h
.PHONY: clean all install mpi python .PHONY: clean all install mpi python
all: lib/librabit.a lib/librabit_mock.a wrapper/librabit_wrapper.so wrapper/librabit_wrapper_mock.so all: lib/librabit.a lib/librabit_mock.a wrapper/librabit_wrapper.so wrapper/librabit_wrapper_mock.so lib/librabit_base.a
mpi: lib/librabit_mpi.a wrapper/librabit_wrapper_mpi.so mpi: lib/librabit_mpi.a wrapper/librabit_wrapper_mpi.so
python: wrapper/librabit_wrapper.so wrapper/librabit_wrapper_mock.so python: wrapper/librabit_wrapper.so wrapper/librabit_wrapper_mock.so
@ -26,8 +26,10 @@ $(BPATH)/allreduce_robust.o: src/allreduce_robust.cc $(HEADERS)
$(BPATH)/engine_mpi.o: src/engine_mpi.cc $(HEADERS) $(BPATH)/engine_mpi.o: src/engine_mpi.cc $(HEADERS)
$(BPATH)/engine_empty.o: src/engine_empty.cc $(HEADERS) $(BPATH)/engine_empty.o: src/engine_empty.cc $(HEADERS)
$(BPATH)/engine_mock.o: src/engine_mock.cc $(HEADERS) $(BPATH)/engine_mock.o: src/engine_mock.cc $(HEADERS)
$(BPATH)/engine_base.o: src/engine_base.cc $(HEADERS)
lib/librabit.a: $(BPATH)/allreduce_base.o $(BPATH)/allreduce_robust.o $(BPATH)/engine.o lib/librabit.a: $(BPATH)/allreduce_base.o $(BPATH)/allreduce_robust.o $(BPATH)/engine.o
lib/librabit_base.a: $(BPATH)/allreduce_base.o $(BPATH)/engine_base.o
lib/librabit_mock.a: $(BPATH)/allreduce_base.o $(BPATH)/allreduce_robust.o $(BPATH)/engine_mock.o lib/librabit_mock.a: $(BPATH)/allreduce_base.o $(BPATH)/allreduce_robust.o $(BPATH)/engine_mock.o
lib/librabit_empty.a: $(BPATH)/engine_empty.o lib/librabit_empty.a: $(BPATH)/engine_empty.o
lib/librabit_mpi.a: $(MPIOBJ) lib/librabit_mpi.a: $(MPIOBJ)

View File

@ -135,7 +135,6 @@ template<typename OP, typename DType>
inline void Allreduce(DType *sendrecvbuf, size_t count, inline void Allreduce(DType *sendrecvbuf, size_t count,
void (*prepare_fun)(void *arg) = NULL, void (*prepare_fun)(void *arg) = NULL,
void *prepare_arg = NULL); void *prepare_arg = NULL);
// C++11 support for lambda prepare function // C++11 support for lambda prepare function
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
/*! /*!
@ -238,11 +237,13 @@ class ReduceHandle;
} // namespace engine } // namespace engine
/*! /*!
* \brief template class to make customized reduce and all reduce easy * \brief template class to make customized reduce and all reduce easy
* Do not use reducer directly in the function you call Finalize, because the destructor can execute after Finalize * Do not use reducer directly in the function you call Finalize,
* because the destructor can execute after Finalize
* \tparam DType data type that to be reduced * \tparam DType data type that to be reduced
* DType must be a struct, with no pointer, and contain a function Reduce(const DType &d); * \tparam freduce the customized reduction function
* DType must be a struct, with no pointer
*/ */
template<typename DType> template<typename DType, void (*freduce)(DType &dst, const DType &src)>
class Reducer { class Reducer {
public: public:
Reducer(void); Reducer(void);
@ -280,7 +281,8 @@ class Reducer {
* Do not use reducer directly in the function you call Finalize, because the destructor can execute after Finalize * Do not use reducer directly in the function you call Finalize, because the destructor can execute after Finalize
* *
* \tparam DType data type that to be reduced, DType must contain the following functions: * \tparam DType data type that to be reduced, DType must contain the following functions:
* (1) Save(IStream &fs) (2) Load(IStream &fs) (3) Reduce(const DType &d); * \tparam freduce the customized reduction function
* (1) Save(IStream &fs) (2) Load(IStream &fs) (3) Reduce(const DType &src, size_t max_nbyte)
*/ */
template<typename DType> template<typename DType>
class SerializeReducer { class SerializeReducer {

View File

@ -195,8 +195,8 @@ inline int VersionNumber(void) {
// Code to handle customized Reduce // Code to handle customized Reduce
// --------------------------------- // ---------------------------------
// function to perform reduction for Reducer // function to perform reduction for Reducer
template<typename DType> template<typename DType, void (*freduce)(DType &dst, const DType &src)>
inline void ReducerFunc_(const void *src_, void *dst_, int len_, const MPI::Datatype &dtype) { inline void ReducerSafe_(const void *src_, void *dst_, int len_, const MPI::Datatype &dtype) {
const size_t kUnit = sizeof(DType); const size_t kUnit = sizeof(DType);
const char *psrc = reinterpret_cast<const char*>(src_); const char *psrc = reinterpret_cast<const char*>(src_);
char *pdst = reinterpret_cast<char*>(dst_); char *pdst = reinterpret_cast<char*>(dst_);
@ -205,18 +205,32 @@ inline void ReducerFunc_(const void *src_, void *dst_, int len_, const MPI::Data
// use memcpy to avoid alignment issue // use memcpy to avoid alignment issue
std::memcpy(&tdst, pdst + i * kUnit, sizeof(tdst)); std::memcpy(&tdst, pdst + i * kUnit, sizeof(tdst));
std::memcpy(&tsrc, psrc + i * kUnit, sizeof(tsrc)); std::memcpy(&tsrc, psrc + i * kUnit, sizeof(tsrc));
tdst.Reduce(tsrc); freduce(tdst, tsrc);
std::memcpy(pdst + i * kUnit, &tdst, sizeof(tdst)); std::memcpy(pdst + i * kUnit, &tdst, sizeof(tdst));
} }
} }
template<typename DType> // function to perform reduction for Reducer
inline Reducer<DType>::Reducer(void) { template<typename DType, void (*freduce)(DType &dst, const DType &src)>
this->handle_.Init(ReducerFunc_<DType>, sizeof(DType)); inline void ReducerAlign_(const void *src_, void *dst_, int len_, const MPI::Datatype &dtype) {
const DType *psrc = reinterpret_cast<const DType*>(src_);
DType *pdst = reinterpret_cast<DType*>(dst_);
for (int i = 0; i < len_; ++i) {
freduce(pdst[i], psrc[i]);
}
} }
template<typename DType> template<typename DType, void (*freduce)(DType &dst, const DType &src)>
inline void Reducer<DType>::Allreduce(DType *sendrecvbuf, size_t count, inline Reducer<DType, freduce>::Reducer(void) {
void (*prepare_fun)(void *arg), // it is safe to directly use handle for aligned data types
void *prepare_arg) { if (sizeof(DType) == 8 || sizeof(DType) == 4 || sizeof(DType) == 1) {
this->handle_.Init(ReducerAlign_<DType, freduce>, sizeof(DType));
} else {
this->handle_.Init(ReducerSafe_<DType, freduce>, sizeof(DType));
}
}
template<typename DType, void (*freduce)(DType &dst, const DType &src)>
inline void Reducer<DType, freduce>::Allreduce(DType *sendrecvbuf, size_t count,
void (*prepare_fun)(void *arg),
void *prepare_arg) {
handle_.Allreduce(sendrecvbuf, sizeof(DType), count, prepare_fun, prepare_arg); handle_.Allreduce(sendrecvbuf, sizeof(DType), count, prepare_fun, prepare_arg);
} }
// function to perform reduction for SerializeReducer // function to perform reduction for SerializeReducer

View File

@ -17,11 +17,15 @@
namespace rabit { namespace rabit {
namespace engine { namespace engine {
// singleton sync manager // singleton sync manager
#ifndef RABIT_USE_BASE
#ifndef RABIT_USE_MOCK #ifndef RABIT_USE_MOCK
AllreduceRobust manager; AllreduceRobust manager;
#else #else
AllreduceMock manager; AllreduceMock manager;
#endif #endif
#else
AllreduceBase manager;
#endif
/*! \brief intiialize the synchronization module */ /*! \brief intiialize the synchronization module */
void Init(int argc, char *argv[]) { void Init(int argc, char *argv[]) {

15
src/engine_base.cc Normal file
View File

@ -0,0 +1,15 @@
/*!
* Copyright (c) 2014 by Contributors
* \file engine_mock.cc
* \brief this is an engine implementation that will
* insert failures in certain call point, to test if the engine is robust to failure
* \author Tianqi Chen
*/
// define use MOCK, os we will use mock Manager
#define _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_DEPRECATE
#define NOMINMAX
// switch engine to AllreduceMock
#define RABIT_USE_BASE
#include "./engine.cc"

View File

@ -159,12 +159,17 @@ void ReduceHandle::Init(IEngine::ReduceFunction redfunc, size_t type_nbytes) {
utils::Assert(handle_ == NULL, "cannot initialize reduce handle twice"); utils::Assert(handle_ == NULL, "cannot initialize reduce handle twice");
if (type_nbytes != 0) { if (type_nbytes != 0) {
MPI::Datatype *dtype = new MPI::Datatype(); MPI::Datatype *dtype = new MPI::Datatype();
*dtype = MPI::CHAR.Create_contiguous(type_nbytes); if (type_nbytes % 8 == 0) {
*dtype = MPI::LONG.Create_contiguous(type_nbytes / sizeof(long));
} else if (type_nbytes % 4 == 0) {
*dtype = MPI::INT.Create_contiguous(type_nbytes / sizeof(int));
} else {
*dtype = MPI::CHAR.Create_contiguous(type_nbytes);
}
dtype->Commit(); dtype->Commit();
created_type_nbytes_ = type_nbytes; created_type_nbytes_ = type_nbytes;
htype_ = dtype; htype_ = dtype;
} }
MPI::Op *op = new MPI::Op(); MPI::Op *op = new MPI::Op();
MPI::User_function *pf = redfunc; MPI::User_function *pf = redfunc;
op->Init(pf, true); op->Init(pf, true);
@ -183,7 +188,13 @@ void ReduceHandle::Allreduce(void *sendrecvbuf,
} else { } else {
dtype->Free(); dtype->Free();
} }
*dtype = MPI::CHAR.Create_contiguous(type_nbytes); if (type_nbytes % 8 == 0) {
*dtype = MPI::LONG.Create_contiguous(type_nbytes / sizeof(long));
} else if (type_nbytes % 4 == 0) {
*dtype = MPI::INT.Create_contiguous(type_nbytes / sizeof(int));
} else {
*dtype = MPI::CHAR.Create_contiguous(type_nbytes);
}
dtype->Commit(); dtype->Commit();
created_type_nbytes_ = type_nbytes; created_type_nbytes_ = type_nbytes;
} }

2
windows/.gitignore vendored
View File

@ -1,6 +1,6 @@
*.suo *.suo
*.exp *.exp
*.sdf *sdf
*.exe *.exe
ipch ipch
x64 x64

View File

@ -105,7 +105,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>..\x64\Release\rabit.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>$(OutDir)\rabit.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>

View File

@ -4,8 +4,14 @@ Microsoft Visual Studio Solution File, Format Version 11.00
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rabit", "rabit\rabit.vcxproj", "{D7B77D06-4F5F-4BD7-B81E-7CC8EBBE684F}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rabit", "rabit\rabit.vcxproj", "{D7B77D06-4F5F-4BD7-B81E-7CC8EBBE684F}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "basic", "basic\basic.vcxproj", "{A6A95246-EB0A-46BA-9471-5939CB6B0006}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "basic", "basic\basic.vcxproj", "{A6A95246-EB0A-46BA-9471-5939CB6B0006}"
ProjectSection(ProjectDependencies) = postProject
{D7B77D06-4F5F-4BD7-B81E-7CC8EBBE684F} = {D7B77D06-4F5F-4BD7-B81E-7CC8EBBE684F}
EndProjectSection
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rabit_wrapper", "rabit_wrapper\rabit_wrapper.vcxproj", "{2F89A7C5-CA4F-4D77-A728-6702D9F33F9F}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rabit_wrapper", "rabit_wrapper\rabit_wrapper.vcxproj", "{2F89A7C5-CA4F-4D77-A728-6702D9F33F9F}"
ProjectSection(ProjectDependencies) = postProject
{D7B77D06-4F5F-4BD7-B81E-7CC8EBBE684F} = {D7B77D06-4F5F-4BD7-B81E-7CC8EBBE684F}
EndProjectSection
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution

View File

@ -106,7 +106,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>..\x64\Release\rabit.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>$(OutDir)\rabit.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>