#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#define safe_xgboost(err) \
if ((err) != 0) { \
fprintf(stderr, "%s:%d: error in %s: %s\n", __FILE__, __LINE__, #err, \
XGBGetLastError()); \
exit(1); \
}
#define safe_malloc(ptr) \
if ((ptr) == NULL) { \
fprintf(stderr, "%s:%d: Failed to allocate memory.\n", __FILE__, \
__LINE__); \
exit(1); \
}
#define N_SAMPLES 128
#define N_FEATURES 16
struct _Matrix {
float *data;
size_t shape[2];
char _array_intrerface[256];
};
typedef struct _Matrix *
Matrix;
void Matrix_Create(
Matrix *
self,
float const *data,
size_t n_samples,
size_t n_features) {
if (self == NULL) {
fprintf(stderr, "Invalid pointer to %s\n", __func__);
exit(-1);
}
*
self = (
Matrix)malloc(
sizeof(
struct _Matrix));
safe_malloc(*self);
(*self)->data = (float *)malloc(n_samples * n_features * sizeof(float));
safe_malloc((*self)->data);
(*self)->shape[0] = n_samples;
(*self)->shape[1] = n_features;
if (data != NULL) {
memcpy((*self)->data, data,
(*self)->shape[0] * (*self)->shape[1] * sizeof(float));
}
}
void Matrix_Random(
Matrix *
self,
size_t n_samples,
size_t n_features) {
Matrix_Create(self, NULL, n_samples, n_features);
for (size_t i = 0; i < n_samples * n_features; ++i) {
float x = (float)rand() / (float)(RAND_MAX);
(*self)->data[i] = x;
}
}
char const *Matrix_ArrayInterface(
Matrix self) {
char const template[] = "{\"data\": [%lu, true], \"shape\": [%lu, %lu], "
"\"typestr\": \"<f4\", \"version\": 3}";
memset(self->_array_intrerface, '\0', sizeof(self->_array_intrerface));
sprintf(self->_array_intrerface, template, (size_t)self->data, self->shape[0],
self->shape[1]);
return self->_array_intrerface;
}
size_t Matrix_NSamples(
Matrix self) {
return self->shape[0]; }
size_t Matrix_NFeatures(
Matrix self) {
return self->shape[1]; }
float Matrix_At(
Matrix self,
size_t i,
size_t j) {
return self->data[i * self->shape[1] + j];
}
void Matrix_Print(
Matrix self) {
for (size_t i = 0; i < Matrix_NSamples(self); i++) {
for (size_t j = 0; j < Matrix_NFeatures(self); ++j) {
printf("%f, ", Matrix_At(self, i, j));
}
}
printf("\n");
}
void Matrix_Free(
Matrix self) {
if (self != NULL) {
if (self->data != NULL) {
self->shape[0] = 0;
self->shape[1] = 0;
free(self->data);
self->data = NULL;
}
free(self);
}
}
int main() {
Matrix_Random(&X, N_SAMPLES, N_FEATURES);
Matrix_Random(&y, N_SAMPLES, 1);
char const *X_interface = Matrix_ArrayInterface(X);
char config[] = "{\"nthread\": 16, \"missing\": NaN}";
DMatrix Xy;
DMatrix cache[] = {Xy};
Booster booster;
size_t n_rounds = 10;
for (size_t i = 0; i < n_rounds; ++i) {
}
{
char const config[] =
"{\"training\": false, \"type\": 0, "
"\"iteration_begin\": 0, \"iteration_end\": 0, \"strict_shape\": true}";
uint64_t const *out_shape;
uint64_t out_dim;
float const *out_results;
&out_dim, &out_results));
if (out_dim != 2 || out_shape[0] != N_SAMPLES || out_shape[1] != 1) {
fprintf(stderr, "Regression model should output prediction as vector.");
exit(-1);
}
Matrix_Create(&predt, out_results, out_shape[0], out_shape[1]);
printf("Results from prediction\n");
Matrix_Print(predt);
Matrix_Free(predt);
}
{
char const config[] = "{\"type\": 0, \"iteration_begin\": 0, "
"\"iteration_end\": 0, \"strict_shape\": true, "
"\"cache_id\": 0, \"missing\": NaN}";
uint64_t const *out_shape;
uint64_t out_dim;
float const *out_results;
char const *X_interface = Matrix_ArrayInterface(X);
&out_shape, &out_dim, &out_results));
if (out_dim != 2 || out_shape[0] != N_SAMPLES || out_shape[1] != 1) {
fprintf(stderr,
"Regression model should output prediction as vector, %lu, %lu",
out_dim, out_shape[0]);
exit(-1);
}
Matrix_Create(&predt, out_results, out_shape[0], out_shape[1]);
printf("Results from inplace prediction\n");
Matrix_Print(predt);
Matrix_Free(predt);
}
Matrix_Free(X);
Matrix_Free(y);
return 0;
}
C API of XGBoost, used for interfacing to other languages.
int XGBoosterFree(BoosterHandle handle)
free obj in handle
int XGBoosterUpdateOneIter(BoosterHandle handle, int iter, DMatrixHandle dtrain)
update the model in one round using dtrain
int XGBoosterCreate(const DMatrixHandle dmats[], bst_ulong len, BoosterHandle *out)
create xgboost learner
int XGDMatrixFree(DMatrixHandle handle)
free space in data matrix
int XGDMatrixCreateFromDense(char const *data, char const *config, DMatrixHandle *out)
Create a matrix from dense array.
int XGDMatrixSetDenseInfo(DMatrixHandle handle, const char *field, void const *data, bst_ulong size, int type)
void * BoosterHandle
handle to Booster
Definition: c_api.h:52
void * DMatrixHandle
handle to DMatrix
Definition: c_api.h:50
int XGBoosterPredictFromDense(BoosterHandle handle, char const *values, char const *config, DMatrixHandle m, bst_ulong const **out_shape, bst_ulong *out_dim, const float **out_result)
Inplace prediction from CPU dense matrix.
int XGBoosterPredictFromDMatrix(BoosterHandle handle, DMatrixHandle dmat, char const *config, bst_ulong const **out_shape, bst_ulong *out_dim, float const **out_result)
Make prediction from DMatrix, replacing XGBoosterPredict.
int XGBoosterSaveModel(BoosterHandle handle, const char *fname)
Save model into existing file.
int XGBoosterLoadModel(BoosterHandle handle, const char *fname)
Load model from existing file.
Tensor< T, 2 > Matrix
Definition: linalg.h:960