add subtree folder
This commit is contained in:
parent
9695c51ce1
commit
07da390575
1
subtree/README.md
Normal file
1
subtree/README.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
This folder contains git subtree projects of xgboost
|
||||||
@ -1,35 +0,0 @@
|
|||||||
export CC = gcc
|
|
||||||
export CXX = g++
|
|
||||||
export MPICXX = mpicxx
|
|
||||||
export LDFLAGS= -pthread -lm
|
|
||||||
export CFLAGS = -Wall -O3 -msse2 -Wno-unknown-pragmas -fPIC -I../src
|
|
||||||
|
|
||||||
ifeq ($(no_omp),1)
|
|
||||||
CFLAGS += -DDISABLE_OPENMP
|
|
||||||
else
|
|
||||||
CFLAGS += -fopenmp
|
|
||||||
endif
|
|
||||||
|
|
||||||
# specify tensor path
|
|
||||||
BIN = test_group_data test_quantile test_allreduce
|
|
||||||
OBJ = sync_tcp.o
|
|
||||||
.PHONY: clean all
|
|
||||||
|
|
||||||
all: $(BIN) $(MPIBIN)
|
|
||||||
|
|
||||||
sync_tcp.o: ../src/sync/sync_tcp.cpp ../src/utils/*.h
|
|
||||||
|
|
||||||
test_group_data: test_group_data.cpp ../src/utils/*.h
|
|
||||||
test_quantile: test_quantile.cpp ../src/utils/*.h
|
|
||||||
test_allreduce: test_allreduce.cpp ../src/utils/*.h ../src/sync/sync.h sync_tcp.o
|
|
||||||
$(BIN) :
|
|
||||||
$(CXX) $(CFLAGS) $(LDFLAGS) -o $@ $(filter %.cpp %.o %.c, $^)
|
|
||||||
|
|
||||||
$(OBJ) :
|
|
||||||
$(CXX) -c $(CFLAGS) -o $@ $(firstword $(filter %.cpp %.c, $^) )
|
|
||||||
|
|
||||||
$(MPIBIN) :
|
|
||||||
$(MPICXX) $(CFLAGS) $(LDFLAGS) -o $@ $(filter %.cpp %.o %.c, $^)
|
|
||||||
|
|
||||||
clean:
|
|
||||||
$(RM) $(BIN) $(MPIBIN) *~
|
|
||||||
@ -1,42 +0,0 @@
|
|||||||
#!/usr/bin/python
|
|
||||||
import math
|
|
||||||
import sys
|
|
||||||
import random
|
|
||||||
import subprocess
|
|
||||||
|
|
||||||
funcs = {
|
|
||||||
'seq': 'lambda n: sorted([(x,1) for x in range(1,n+1)], key = lambda x:random.random())',
|
|
||||||
'seqlogw': 'lambda n: sorted([(x, math.log(x)) for x in range(1,n+1)], key = lambda x:random.random())',
|
|
||||||
'lots0': 'lambda n: sorted([(max(x - n*3/4,0), 1) for x in range(1,n+1)], key = lambda x:random.random())',
|
|
||||||
'lots9': 'lambda n: sorted([(9 if x > n / 4 else x, 1) for x in range(1,n+1)], key = lambda x:random.random())',
|
|
||||||
'lotsm': 'lambda n: sorted([(n/8 if x > n / 4 else x, 1) for x in range(1,n+1)], key = lambda x:random.random())',
|
|
||||||
'lotsmr': 'lambda n: sorted([( x * 4 / n + n / 20 if x > n / 10 else x, 1) for x in range(1,n+1)], key = lambda x:random.random())',
|
|
||||||
'lotsmr2': 'lambda n: sorted([( x * 10 / n + n / 20 if x > n / 10 else x, 1) for x in range(1,n+1)], key = lambda x:random.random())'
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(sys.argv) < 3:
|
|
||||||
print 'Usage: python mkquantest.py <maxn> <eps> [generate-type] [ndata]|./test_quantile [solver]'
|
|
||||||
print 'test_quantile need to be compiled, solver can be gk(GK nonweight version), wq(weighted version), wx(weighthed version, with prune optimized for heavy hitter)'
|
|
||||||
print 'Possible generate-types:'
|
|
||||||
for k, v in funcs.items():
|
|
||||||
print '\t%s: %s' % (k, v)
|
|
||||||
print 'Example: ./mkquantest.py 50000 0.3 lotsmr |./test_quantile wq'
|
|
||||||
exit(-1)
|
|
||||||
random.seed(0)
|
|
||||||
maxn = int(sys.argv[1])
|
|
||||||
eps = float(sys.argv[2])
|
|
||||||
if len(sys.argv) > 3:
|
|
||||||
method = sys.argv[3]
|
|
||||||
assert method in funcs, ('cannot find method %s' % method)
|
|
||||||
else:
|
|
||||||
method = 'seq'
|
|
||||||
if len(sys.argv) > 4:
|
|
||||||
ndata = int(sys.argv[4])
|
|
||||||
assert ndata <= maxn, 'ndata must be smaller than maxn'
|
|
||||||
else:
|
|
||||||
ndata = maxn
|
|
||||||
|
|
||||||
fo = sys.stdout
|
|
||||||
fo.write('%d\t%g\n' % (maxn, eps))
|
|
||||||
for x, w in eval(funcs[method])(ndata):
|
|
||||||
fo.write(str(x)+'\t'+str(w)+'\n')
|
|
||||||
@ -1,124 +0,0 @@
|
|||||||
#include <sync/sync.h>
|
|
||||||
#include <utils/utils.h>
|
|
||||||
#include <cstdio>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
using namespace xgboost;
|
|
||||||
|
|
||||||
inline void TestMax(size_t n) {
|
|
||||||
int rank = sync::GetRank();
|
|
||||||
int nproc = sync::GetWorldSize();
|
|
||||||
|
|
||||||
std::vector<float> ndata(n);
|
|
||||||
for (size_t i = 0; i < ndata.size(); ++i) {
|
|
||||||
ndata[i] = (i * (rank+1)) % 111;
|
|
||||||
}
|
|
||||||
sync::AllReduce(&ndata[0], ndata.size(), sync::kMax);
|
|
||||||
for (size_t i = 0; i < ndata.size(); ++i) {
|
|
||||||
float rmax = (i * 1) % 111;
|
|
||||||
for (int r = 0; r < nproc; ++r) {
|
|
||||||
rmax = std::max(rmax, (float)((i * (r+1)) % 111));
|
|
||||||
}
|
|
||||||
utils::Check(rmax == ndata[i], "[%d] TestMax check failure", rank);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void TestSum(size_t n) {
|
|
||||||
int rank = sync::GetRank();
|
|
||||||
int nproc = sync::GetWorldSize();
|
|
||||||
const int z = 131;
|
|
||||||
|
|
||||||
std::vector<float> ndata(n);
|
|
||||||
for (size_t i = 0; i < ndata.size(); ++i) {
|
|
||||||
ndata[i] = (i * (rank+1)) % z;
|
|
||||||
}
|
|
||||||
sync::AllReduce(&ndata[0], ndata.size(), sync::kSum);
|
|
||||||
for (size_t i = 0; i < ndata.size(); ++i) {
|
|
||||||
float rsum = 0.0f;
|
|
||||||
for (int r = 0; r < nproc; ++r) {
|
|
||||||
rsum += (float)((i * (r+1)) % z);
|
|
||||||
}
|
|
||||||
utils::Check(fabsf(rsum - ndata[i]) < 1e-5 ,
|
|
||||||
"[%d] TestSum check failure, local=%g, allreduce=%g", rank, rsum, ndata[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Rec {
|
|
||||||
double rmax;
|
|
||||||
double rmin;
|
|
||||||
double rsum;
|
|
||||||
Rec() {}
|
|
||||||
Rec(double r) {
|
|
||||||
rmax = rmin = rsum = r;
|
|
||||||
}
|
|
||||||
inline void Reduce(const Rec &b) {
|
|
||||||
rmax = std::max(b.rmax, rmax);
|
|
||||||
rmin = std::max(b.rmin, rmin);
|
|
||||||
rsum += b.rsum;
|
|
||||||
}
|
|
||||||
inline void CheckSameAs(const Rec &b) {
|
|
||||||
if (rmax != b.rmax || rmin != b.rmin || fabs(rsum - b.rsum) > 1e-6) {
|
|
||||||
utils::Error("[%d] TestReducer check failure", sync::GetRank());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
inline void TestReducer(int n) {
|
|
||||||
int rank = sync::GetRank();
|
|
||||||
int nproc = sync::GetWorldSize();
|
|
||||||
const int z = 131;
|
|
||||||
sync::Reducer<Rec> red;
|
|
||||||
std::vector<Rec> ndata(n);
|
|
||||||
for (size_t i = 0; i < ndata.size(); ++i) {
|
|
||||||
ndata[i] = Rec((i * (rank+1)) % z);
|
|
||||||
}
|
|
||||||
red.AllReduce(&ndata[0], ndata.size());
|
|
||||||
|
|
||||||
for (size_t i = 0; i < ndata.size(); ++i) {
|
|
||||||
Rec rec((i * 1) % z);
|
|
||||||
for (int r = 1; r < nproc; ++r) {
|
|
||||||
rec.Reduce(Rec((i * (r+1)) % z));
|
|
||||||
}
|
|
||||||
rec.CheckSameAs(ndata[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void TestBcast(size_t n, int root) {
|
|
||||||
int rank = sync::GetRank();
|
|
||||||
std::string s; s.resize(n);
|
|
||||||
for (size_t i = 0; i < n; ++i) {
|
|
||||||
s[i] = char(i % 126 + 1);
|
|
||||||
}
|
|
||||||
std::string res;
|
|
||||||
if (root == rank) {
|
|
||||||
res = s;
|
|
||||||
sync::Bcast(&res, root);
|
|
||||||
} else {
|
|
||||||
sync::Bcast(&res, root);
|
|
||||||
}
|
|
||||||
utils::Check(res == s, "[%d] TestBcast fail", rank);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
|
||||||
if (argc < 2) {
|
|
||||||
printf("Usage: <ndata>\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int n = atoi(argv[1]);
|
|
||||||
sync::Init(argc, argv);
|
|
||||||
int rank = sync::GetRank();
|
|
||||||
//int nproc = sync::GetWorldSize();
|
|
||||||
std::string name = sync::GetProcessorName();
|
|
||||||
printf("[%d] start at %s\n", rank, name.c_str());
|
|
||||||
TestMax(n);
|
|
||||||
printf("[%d] TestMax pass\n", rank);
|
|
||||||
TestSum(n);
|
|
||||||
printf("[%d] TestSum pass\n", rank);
|
|
||||||
TestReducer(n);
|
|
||||||
printf("[%d] TestReducer pass\n", rank);
|
|
||||||
sync::Finalize();
|
|
||||||
printf("[%d] all check pass\n", rank);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@ -1,84 +0,0 @@
|
|||||||
#include <cstdio>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <vector>
|
|
||||||
#include <utility>
|
|
||||||
#include <ctime>
|
|
||||||
#include <utils/group_data.h>
|
|
||||||
#include <utils/random.h>
|
|
||||||
#include <utils/omp.h>
|
|
||||||
#include <utils/utils.h>
|
|
||||||
|
|
||||||
using namespace xgboost::utils;
|
|
||||||
using namespace xgboost;
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
|
||||||
if (argc < 3) {
|
|
||||||
printf("Usage: <nkey> <ndata> pnthread]\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (argc > 3) {
|
|
||||||
omp_set_num_threads(atoi(argv[3]));
|
|
||||||
}
|
|
||||||
random::Seed(0);
|
|
||||||
unsigned nkey = static_cast<unsigned>(atoi(argv[1]));
|
|
||||||
size_t ndata = static_cast<size_t>(atol(argv[2]));
|
|
||||||
|
|
||||||
std::vector<unsigned> keys;
|
|
||||||
std::vector< std::pair<unsigned, unsigned> > raw;
|
|
||||||
raw.reserve(ndata); keys.reserve(ndata);
|
|
||||||
for (size_t i = 0; i < ndata; ++i) {
|
|
||||||
unsigned key = random::NextUInt32(nkey);
|
|
||||||
utils::Check(key < nkey, "key exceed bound\n");
|
|
||||||
raw.push_back(std::make_pair(key, i));
|
|
||||||
keys.push_back(key);
|
|
||||||
}
|
|
||||||
printf("loading finish, start working\n");
|
|
||||||
time_t start_t = time(NULL);
|
|
||||||
int nthread;
|
|
||||||
#pragma omp parallel
|
|
||||||
{
|
|
||||||
nthread = omp_get_num_threads();
|
|
||||||
}
|
|
||||||
std::vector<size_t> rptr;
|
|
||||||
std::vector<unsigned> data;
|
|
||||||
ParallelGroupBuilder<unsigned> builder(&rptr, &data);
|
|
||||||
builder.InitBudget(0, nthread);
|
|
||||||
|
|
||||||
size_t nstep = (raw.size() +nthread-1)/ nthread;
|
|
||||||
#pragma omp parallel
|
|
||||||
{
|
|
||||||
int tid = omp_get_thread_num();
|
|
||||||
size_t begin = tid * nstep;
|
|
||||||
size_t end = std::min((tid + 1) * nstep, raw.size());
|
|
||||||
for (size_t i = begin; i < end; ++i) {
|
|
||||||
builder.AddBudget(raw[i].first, tid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
double first_cost = time(NULL) - start_t;
|
|
||||||
builder.InitStorage();
|
|
||||||
|
|
||||||
#pragma omp parallel
|
|
||||||
{
|
|
||||||
int tid = omp_get_thread_num();
|
|
||||||
size_t begin = tid * nstep;
|
|
||||||
size_t end = std::min((tid + 1)* nstep, raw.size());
|
|
||||||
for (size_t i = begin; i < end; ++i) {
|
|
||||||
builder.Push(raw[i].first, raw[i].second, tid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
double second_cost = time(NULL) - start_t;
|
|
||||||
printf("all finish, phase1=%g sec, phase2=%g sec\n", first_cost, second_cost);
|
|
||||||
Check(rptr.size() <= nkey+1, "nkey exceed bound");
|
|
||||||
Check(rptr.back() == ndata, "data shape inconsistent");
|
|
||||||
for (size_t i = 0; i < rptr.size()-1; ++ i) {
|
|
||||||
Check(rptr[i] <= rptr[i+1], "rptr error");
|
|
||||||
for (size_t j = rptr[i]; j < rptr[i+1]; ++j) {
|
|
||||||
unsigned pos = data[j];
|
|
||||||
Check(pos < keys.size(), "invalid pos");
|
|
||||||
Check(keys[pos] == i, "invalid key entry");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
printf("all check pass\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@ -1,92 +0,0 @@
|
|||||||
#include <vector>
|
|
||||||
#include <utils/quantile.h>
|
|
||||||
#include <ctime>
|
|
||||||
using namespace xgboost;
|
|
||||||
|
|
||||||
|
|
||||||
struct Entry {
|
|
||||||
double x, w, rmin;
|
|
||||||
inline bool operator<(const Entry &e) const {
|
|
||||||
return x < e.x;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
inline void MakeQuantile(std::vector<Entry> &dat) {
|
|
||||||
std::sort(dat.begin(), dat.end());
|
|
||||||
size_t top = 0;
|
|
||||||
double wsum = 0.0;
|
|
||||||
for (size_t i = 0; i < dat.size();) {
|
|
||||||
size_t j = i + 1;
|
|
||||||
for (;j < dat.size() && dat[i].x == dat[j].x; ++j) {
|
|
||||||
dat[i].w += dat[j].w;
|
|
||||||
}
|
|
||||||
dat[top] = dat[i];
|
|
||||||
dat[top].rmin = wsum;
|
|
||||||
wsum += dat[top].w;
|
|
||||||
++top;
|
|
||||||
i = j;
|
|
||||||
}
|
|
||||||
dat.resize(top);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Summary>
|
|
||||||
inline void verifyWQ(std::vector<Entry> &dat, Summary out) {
|
|
||||||
MakeQuantile(dat);
|
|
||||||
size_t j = 0;
|
|
||||||
double err = 0.0;
|
|
||||||
const double eps = 1e-4;
|
|
||||||
for (size_t i = 0; i < out.size; ++i) {
|
|
||||||
while (j < dat.size() && dat[j].x < out.data[i].value) ++j;
|
|
||||||
utils::Assert(j < dat.size() && fabs(dat[j].x - out.data[i].value) < eps, "bug");
|
|
||||||
err = std::min(dat[j].rmin - out.data[i].rmin, err);
|
|
||||||
err = std::min(out.data[i].rmax - dat[j].rmin + dat[j].w, err);
|
|
||||||
err = std::min(dat[j].w - out.data[i].wmin, err);
|
|
||||||
}
|
|
||||||
if (err < 0.0) err = -err;
|
|
||||||
printf("verify correctness, max-constraint-violation=%g (0 means perfect, coubld be nonzero due to floating point)\n", err);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Sketch, typename RType>
|
|
||||||
inline typename Sketch::SummaryContainer test(std::vector<Entry> &dat) {
|
|
||||||
Sketch sketch;
|
|
||||||
size_t n;
|
|
||||||
double wsum = 0.0;
|
|
||||||
float eps;
|
|
||||||
utils::Check(scanf("%lu%f", &n, &eps) == 2, "needs to start with n eps");
|
|
||||||
sketch.Init(n, eps);
|
|
||||||
Entry e;
|
|
||||||
while (scanf("%lf%lf", &e.x, &e.w) == 2) {
|
|
||||||
dat.push_back(e);
|
|
||||||
wsum += e.w;
|
|
||||||
}
|
|
||||||
clock_t start = clock();
|
|
||||||
for (size_t i = 0; i < dat.size(); ++i) {
|
|
||||||
sketch.Push(dat[i].x, dat[i].w);
|
|
||||||
}
|
|
||||||
double tcost = static_cast<double>(clock() - start) / CLOCKS_PER_SEC;
|
|
||||||
typename Sketch::SummaryContainer out;
|
|
||||||
sketch.GetSummary(&out);
|
|
||||||
double maxerr = static_cast<double>(out.MaxError());
|
|
||||||
out.Print();
|
|
||||||
printf("-------------------------\n");
|
|
||||||
printf("timecost=%g sec\n", tcost);
|
|
||||||
printf("MaxError=%g/%g = %g\n", maxerr, wsum, maxerr / wsum);
|
|
||||||
printf("maxlevel = %lu, usedlevel=%lu, limit_size=%lu\n", sketch.nlevel, sketch.level.size(), sketch.limit_size);
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
|
||||||
const char *method = "wq";
|
|
||||||
if (argc > 1) method = argv[1];
|
|
||||||
std::vector<Entry> dat;
|
|
||||||
if (!strcmp(method, "wq")) {
|
|
||||||
verifyWQ(dat, test<utils::WQuantileSketch<float, float>, float>(dat));
|
|
||||||
}
|
|
||||||
if (!strcmp(method, "wx")) {
|
|
||||||
verifyWQ(dat, test<utils::WXQuantileSketch<float, float>, float>(dat));
|
|
||||||
}
|
|
||||||
if (!strcmp(method, "gk")) {
|
|
||||||
test<utils::GKQuantileSketch<float, unsigned>, unsigned>(dat);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user