├── xgbin └── .gitignore ├── .gitignore ├── LICENSE ├── GNUmakefile ├── README.md ├── xgb_train.py ├── xgboost_test.F90 └── xgb_fortran_api.F90 /xgbin/.gitignore: -------------------------------------------------------------------------------- 1 | *.bin 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | xgboost/ 2 | *.mod 3 | *.o 4 | *.exe 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Christoph Keller 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /GNUmakefile: -------------------------------------------------------------------------------- 1 | .SUFFIXES: .o .f90 .F90 .F .exe .c 2 | 3 | .PHONY: 4 | all clean veryclean 5 | 6 | FC = ifort 7 | #FC = gfortran 8 | #FC = nagfor 9 | 10 | #XGBOOST_LIBDIR = ./xgboost/lib 11 | XGBOOST_LIBDIR = /discover/swdev/gmao_SIteam/Baselibs/TmpBaselibs/ESMA-Baselibs-6.2.14-TEST/x86_64-pc-linux-gnu/ifort_2021.3.0-intelmpi_2021.3.0/Linux/lib64 12 | 13 | INCDIR = include 14 | 15 | all: runtest 16 | 17 | runtest: test.exe 18 | env LD_LIBRARY_PATH=$(LD_LIBRARY_PATH):$(XGBOOST_LIBDIR) ./test.exe 19 | 20 | test.exe: xgboost_test.o xgb_fortran_api.o 21 | $(FC) $(FOPTS) $^ -o $@ -L$(XGBOOST_LIBDIR) -lxgboost 22 | 23 | xgboost_test.o: xgboost_test.F90 xgb_fortran_api.o 24 | 25 | xgb_fortran_api.o: xgb_fortran_api.F90 26 | 27 | FOPTS = -g -traceback 28 | #FOPTS = -g -fbacktrace 29 | #FOPTS = -g -C=all 30 | 31 | .f90.o: 32 | $(FC) $(VOPTS) $(FOPTS) $(DOPTS) -c $< -I$(INCDIR) 33 | 34 | .F90.o: 35 | $(FC) $(VOPTS) $(FOPTS) $(DOPTS) -c $< -I$(INCDIR) 36 | 37 | .F.o: 38 | $(FC) $(VOPTS) $(FOPTS) $(DOPTS) -c $< -I$(INCDIR) 39 | 40 | .cuf.o: 41 | $(FC) $(VOPTS) $(FOPTS) $(DOPTS) -c $< -I$(INCDIR) 42 | 43 | .c.o: 44 | $(CC) $(VOPTS) $(COPTS) $(DOPTS) -c $< -I$(INCDIR) 45 | 46 | clean: 47 | rm -f *.o *.mod core.* *.exe 48 | 49 | veryclean: clean 50 | rm -f *.exe input.nml logfile.* mpp_clock.out.* 51 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Note: stale repository 2 | This repository is not activetly maintained. The XGBoost - Fortran API has been integrated into the [GEOS QuickChem module](https://github.com/GEOS-ESM/QuickChem). See the [corresponding F90 file](https://github.com/GEOS-ESM/QuickChem/blob/main/Shared/xgb_fortran_api.F90) for a more recent version. 3 | 4 | # fortran2xgb 5 | Fortran API for XGBoost 6 | 7 | Interface for calling XGBoost from Fortran. The idea is to train an XGBoost model externally, e.g. in Python, then save that model to disk (in the XGBoost internal binary format, e.g. using Booster.save_model() in Python), and later call the model from Fortran to make a prediction. 8 | The Fortran wrappers that invoke the XGBoost C functions are in xgb_fortran_api.F90. A Fortran test application that creates a very simple XGBoost model and then calls the Fortran wrappers is given in xgb_train.py and xgboost_test.F90, respectively. 9 | 10 | # Requirements 11 | A Python version of XGBoost is required (https://github.com/dmlc/xgboost/tree/master/python-package/xgboost) and needs to be pointed at properly in the GNUmakefile. All tests done with version 0.82. 12 | 13 | # Example 14 | 1. Create dummy xgbooster model and save to file (bst_from_py.bin): 15 | 16 | `python xgb_train.py` 17 | 18 | 2. Compile and execute Fortran code: 19 | 20 | `make` 21 | -------------------------------------------------------------------------------- /xgb_train.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import numpy as np 3 | import xgboost as xgb 4 | import joblib 5 | #from sklearn.externals import joblib 6 | from sklearn.metrics import mean_squared_error, r2_score 7 | from math import sqrt 8 | 9 | def main(args): 10 | ''' 11 | Trains a dummy XGBoost model for 5 input features and one target variable. 12 | The booster model is saved to disk and then reloaded to do a quick check 13 | that the loaded model is identical to the originally created one. 14 | ''' 15 | nrow = 500 16 | ncol = 5 17 | x_np = np.random.rand(nrow,ncol) 18 | y_np = np.random.rand(nrow,1) 19 | train = xgb.DMatrix(x_np,y_np) 20 | param = {'booster' : 'gbtree'} 21 | bst = xgb.train(param,train) 22 | prediction = bst.predict(train) 23 | r2 = r2_score(y_np,prediction) 24 | nrmse = sqrt(mean_squared_error(y_np,prediction))/np.std(y_np) 25 | nmb = np.sum(prediction-y_np)/np.sum(y_np) 26 | print("Backtest scores:") 27 | print("R2 = "+'{0:.2f}'.format(r2)) 28 | print("NRMSE = "+'{0:.2f}'.format(nrmse)) 29 | print("NMB = "+'{0:.2f}'.format(nmb)) 30 | # save 31 | bst.save_model(args.bstfile) 32 | # reload 33 | bst2 = xgb.Booster() 34 | bst2.load_model(args.bstfile) 35 | prediction2 = bst2.predict(train) 36 | r2 = r2_score(prediction,prediction2) 37 | nrmse = sqrt(mean_squared_error(prediction,prediction2))/np.std(prediction) 38 | nmb = np.sum(prediction2-prediction)/np.sum(prediction) 39 | print("Backtest validation using saved and reloaded model (compared to original):") 40 | print("R2 (should be 1.00) = "+'{0:.2f}'.format(r2)) 41 | print("NRMSE (should be 0.00) = "+'{0:.2f}'.format(nrmse)) 42 | print("NMB (should be 0.00) = "+'{0:.2f}'.format(nmb)) 43 | # prediction with all zeros and all ones: 44 | arr = np.zeros((1,ncol)) 45 | p = bst.predict(xgb.DMatrix(arr)) 46 | print("Prediction with all zeros:") 47 | print(p) 48 | arr[:,:] = 1.0 49 | mtrx = xgb.DMatrix(arr) 50 | p = bst.predict(mtrx) 51 | print("Prediction with all ones:") 52 | print(p) 53 | fname = 'xgbin/mtrx_ones_from_py.bin' 54 | mtrx.save_binary(fname) 55 | print('matrix with ones saved to '+fname) 56 | m_ones = xgb.DMatrix(fname) 57 | p = bst.predict(m_ones) 58 | print("Prediction with ones matrix reloaded (should be same as above):") 59 | print(p) 60 | return 61 | 62 | def parse_args(): 63 | p = argparse.ArgumentParser(description='Undef certain variables') 64 | p.add_argument('-f','--bstfile',type=str,help='xgb binary file',default='xgbin/bst_from_py.bin') 65 | return p.parse_args() 66 | 67 | if __name__ == '__main__': 68 | main(parse_args()) 69 | 70 | -------------------------------------------------------------------------------- /xgboost_test.F90: -------------------------------------------------------------------------------- 1 | program xgboost_test 2 | ! Simple interface showing an example on how to call XGBoost from Fortran 3 | ! by invoking the C bindings defined in fortran_api.F90. 4 | ! 5 | ! As an example, this reads a pre-saved booster object from file 'bst.bin' 6 | ! and then makes a prediction using a vector of all ones as input. The booster 7 | ! object is assumed to take 5 input arguments and produce one target value. 8 | ! The booster model can be trained in python and then written to binary file, 9 | ! as e.g. shown in xgb_train.py. 10 | ! 11 | ! History: 12 | ! 2019-10-09 - christoph.a.keller@nasa.gov - Initial version 13 | ! ---------------------------------------------------------------------------- 14 | use iso_c_binding 15 | use xgb_fortran_api 16 | implicit none 17 | 18 | !--- Local variables 19 | integer :: rc 20 | integer(c_int64_t) :: nrow, ncol 21 | ! for booster object 22 | character(len=255) :: fname_bst 23 | integer(c_int64_t) :: dmtrx_len 24 | type(c_ptr) :: bst 25 | ! for XGDMatrix object 26 | type(c_ptr) :: dmtrx 27 | integer(c_int64_t) :: dm_nrow, dm_ncol 28 | integer(c_int) :: silent 29 | real(c_float), allocatable :: carr(:) 30 | character(len=255) :: fname 31 | ! for prediction 32 | integer(c_int) :: option_mask, ntree_limit, training 33 | type(c_ptr) :: cpred 34 | integer(c_int64_t) :: pred_len 35 | real(c_float), pointer :: pred(:) 36 | integer, pointer :: targ(:) 37 | 38 | ! testing new interface 39 | integer, pointer :: oshape(:) 40 | type(c_ptr) :: out_shape 41 | character(len=255) :: json_config 42 | 43 | !--- Parameter 44 | ! missing value 45 | real(c_float), parameter :: miss = -999.0 46 | ! debug flag 47 | logical, parameter :: debug = .true. 48 | logical, parameter :: fulltest = .true. 49 | 50 | !--- Settings 51 | ! Dimension of input array. We assume it's 1x5 (1 prediction, 5 input variables) 52 | fname_bst = 'xgbin/bst_from_py.bin' 53 | nrow = 1 54 | ncol = 5 55 | ! Array to hold input values 56 | allocate(carr(ncol)) 57 | carr(:) = 0.0 58 | ! Settings for prediction 59 | option_mask = 0 60 | ntree_limit = 0 61 | training = 0 62 | ! Silent flag for reading/writing 63 | silent = 0 64 | 65 | !--- Starts here 66 | write(*,*) 'Starting XGBoost program' 67 | 68 | !--- Load booster object 69 | ! Create (dummy) XGDMatrix - this is required in order to create the booster object below 70 | rc = XGDMatrixCreateFromMat_f(carr, nrow, ncol, miss, dmtrx) 71 | if(debug) write(*,*) __FILE__,__LINE__,'Return code: ',rc 72 | ! Check XGDMatrix dimensions 73 | ! number of rows/cols in dmtrx 74 | rc = XGDMatrixNumRow_f(dmtrx, dm_nrow) 75 | if(debug) write(*,*) __FILE__,__LINE__,'Return code: ',rc 76 | ! number of rows/cols in dmtrx 77 | rc = XGDMatrixNumCol_f(dmtrx, dm_ncol) 78 | if(debug) write(*,*) __FILE__,__LINE__,'Return code: ',rc 79 | write(*,*) 'Numbers of rows, cols of DMatrix object: ',dm_nrow,dm_ncol 80 | 81 | ! now create XGBooster object. Content will be loaded into it next 82 | dmtrx_len = 0 83 | rc = XGBoosterCreate_f(dmtrx,dmtrx_len,bst) 84 | if(debug) write(*,*) __FILE__,__LINE__,'Return code: ',rc 85 | ! load XGBooster model from binary file 86 | write(*,*) 'Reading '//trim(fname_bst) 87 | rc = XGBoosterLoadModel_f(bst,fname_bst) 88 | if(debug) write(*,*) __FILE__,__LINE__,'Return code: ',rc 89 | ! To save model to binary file 90 | if ( fulltest ) then 91 | rc = XGBoosterSaveModel_f(bst,'xgbin/bst_from_f90.bin') 92 | if(debug) write(*,*) __FILE__,__LINE__,'Return code: ',rc 93 | endif 94 | 95 | !--- Make prediction with all ones 96 | 97 | allocate(targ(nrow)) 98 | cpred = c_loc(targ) 99 | 100 | ! Create XGDMatrix with all ones 101 | carr(:) = 1.0 102 | rc = XGDMatrixCreateFromMat_f(carr, nrow, ncol, miss, dmtrx) 103 | if(debug) write(*,*) __FILE__,__LINE__,'Return code: ',rc 104 | ! Make prediction. The result will be stored in c pointer cpred 105 | rc = XGBoosterPredict_f(bst,dmtrx,option_mask,ntree_limit,training,pred_len,cpred) 106 | if(debug) write(*,*) __FILE__,__LINE__,'Return code: ',rc 107 | ! Link to fortran pointer pred 108 | call c_f_pointer(cpred, pred, [pred_len]) 109 | write(*,*) 'Prediction with all ones: ',pred 110 | 111 | ! New prediction interface - does not yet work 112 | ! allocate(oshape(2)) 113 | ! out_shape = c_loc(oshape) 114 | ! json_config = 'config/config.json' 115 | ! rc = XGBoosterPredictFromDMatrix_f(bst,dmtrx,json_config,out_shape,pred_len,cpred) 116 | ! if(debug) write(*,*) __FILE__,__LINE__,'Return code: ',rc 117 | ! Link to fortran pointer pred 118 | ! call c_f_pointer(cpred, pred, [pred_len]) 119 | ! write(*,*) 'Prediction with new interface, using all ones: ',pred 120 | 121 | !--- Additional example code for DMatrix 122 | if ( fulltest ) then 123 | ! 1. Save XGDMatrix defined above to binary file. This can then 124 | ! be reloaded, e.g. using XGDMatrixCreateFromFile_f or from 125 | ! Python, e.g.: dmtrx = xgboost.DMatrix('mtrx_ones_from_f90.bin') 126 | fname = 'xgbin/mtrx_ones_from_f90.bin' 127 | rc = XGDMatrixSaveBinary_f(dmtrx, fname, silent) 128 | if(debug) write(*,*) __FILE__,__LINE__,'Return code: ',rc 129 | ! 2. Load XGDMatrix from binary file 130 | rc = XGDMatrixCreateFromFile_f(fname, silent, dmtrx) 131 | if(debug) write(*,*) __FILE__,__LINE__,'Return code: ',rc 132 | ! 3. Make prediction with this matrix - should give same result as above 133 | rc = XGBoosterPredict_f(bst,dmtrx,option_mask,ntree_limit,training,pred_len,cpred) 134 | if(debug) write(*,*) __FILE__,__LINE__,'Return code: ',rc 135 | call c_f_pointer(cpred, pred, [pred_len]) 136 | write(*,*) 'Prediction with data from file: ',pred 137 | endif 138 | 139 | !--- Cleanup 140 | rc = XGBoosterFree_f(bst) 141 | if(debug) write(*,*) __FILE__,__LINE__,'Model freed, return code: ',rc 142 | if (allocated (carr) ) deallocate(carr) 143 | if (associated(pred) ) nullify(pred) 144 | deallocate(targ) 145 | write(*,*) 'All done' 146 | 147 | end program 148 | 149 | -------------------------------------------------------------------------------- /xgb_fortran_api.F90: -------------------------------------------------------------------------------- 1 | module xgb_fortran_api 2 | ! This module contains Fortran interfaces for the XGBoost C API 3 | ! This API does not cover all functions of the XGBoost C API. It 4 | ! currently covers functions to read a previously trained XGBoost 5 | ! model (e.g. trained in Python) from a binary file, and then make 6 | ! a prediction using input values defined either on-the-fly or read 7 | ! from binary file. 8 | ! See xgboost_test.F90 for an example on how to use it within a 9 | ! Fortran program. 10 | ! 11 | ! History: 12 | ! 2019-10-09 - christoph.a.keller@nasa.gov - Initial version 13 | ! ---------------------------------------------------------------------------- 14 | use iso_c_binding 15 | implicit none 16 | 17 | interface 18 | integer(kind=c_int) function XGBoosterLoadModel_c(handle, fname) bind(C, name="XGBoosterLoadModel") 19 | use iso_c_binding, only: c_int, c_char, c_ptr 20 | type(c_ptr), value :: handle ! BoosterHandle 21 | character(len=1, kind=c_char), dimension(*) :: fname 22 | end function 23 | end interface 24 | 25 | interface 26 | integer(c_int) function XGBoosterSaveModel_c(handle, fname) bind(C, name="XGBoosterSaveModel") 27 | use iso_c_binding, only: c_int, c_ptr, c_char 28 | type(c_ptr), value :: handle ! BoosterHandle 29 | character(len=1, kind=c_char), dimension(*) :: fname 30 | end function 31 | end interface 32 | 33 | interface 34 | integer(kind=c_int) function XGDMatrixSaveBinary_c(handle, fname, silent) bind(C, name="XGDMatrixSaveBinary") 35 | use iso_c_binding, only: c_int, c_char, c_ptr 36 | type(c_ptr), value :: handle ! DMatrixHandle 37 | character(len=1, kind=c_char), dimension(*) :: fname 38 | integer(kind=c_int), value :: silent 39 | end function 40 | end interface 41 | 42 | interface 43 | integer(kind=c_int) function XGDMatrixCreateFromFile_c(fname, silent, handle) bind(C, name="XGDMatrixCreateFromFile") 44 | use iso_c_binding, only: c_int, c_char, c_ptr 45 | character(len=1, kind=c_char), dimension(*) :: fname 46 | integer(kind=c_int), value :: silent 47 | type(c_ptr) :: handle ! DMatrixHandle 48 | end function 49 | end interface 50 | 51 | interface 52 | integer(c_int) function XGBoosterPredict_f(handle, dmat, option_mask, ntree_limit, training, length, prediction) & 53 | bind(C, name="XGBoosterPredict") 54 | use iso_c_binding, only: c_int, c_ptr, c_int64_t, c_float, c_double 55 | type(c_ptr), value :: handle ! BoosterHandle 56 | type(c_ptr), value :: dmat ! DMatrixHandle 57 | integer(c_int), value :: option_mask ! option mask 58 | integer(c_int), value :: ntree_limit ! limit number of trees in the prediction 59 | integer(c_int), value :: training ! training 60 | integer(c_int64_t) :: length ! length of prediction 61 | type(c_ptr) :: prediction ! prediction 62 | end function 63 | end interface 64 | 65 | interface 66 | integer(c_int) function XGBoosterPredictFromDMatrix_c(handle, dmat, c_json_config, out_shape, out_dim, prediction) & 67 | bind(C, name="XGBoosterPredictFromDMatrix") 68 | use iso_c_binding, only: c_int, c_char, c_ptr, c_int64_t, c_float, c_double 69 | type(c_ptr), value :: handle ! BoosterHandle 70 | type(c_ptr), value :: dmat ! DMatrixHandle 71 | character(len=1, kind=c_char), dimension(*) :: c_json_config 72 | type(c_ptr) :: out_shape ! length of prediction 73 | integer(c_int64_t) :: out_dim ! length of prediction 74 | type(c_ptr) :: prediction ! prediction 75 | end function 76 | end interface 77 | 78 | interface 79 | integer(c_int) function XGBoosterCreate_f(dmats, len, out) & 80 | bind(c, name="XGBoosterCreate") 81 | use iso_c_binding, only: c_int, c_ptr, c_int64_t 82 | type(c_ptr), value :: dmats ! DMatrixHandle 83 | integer(c_int64_t), value :: len 84 | type(c_ptr) :: out ! BoosterHandle* 85 | end function 86 | end interface 87 | 88 | interface 89 | integer(c_int) function XGDMatrixCreateFromMat_f(data, nrow, ncol, missing, out) & 90 | bind(c, name="XGDMatrixCreateFromMat") 91 | use iso_c_binding, only: c_int, c_ptr, c_float, c_double, c_int64_t 92 | real(c_float) :: data(*) 93 | integer(c_int64_t), value :: nrow 94 | integer(c_int64_t), value :: ncol 95 | real(c_float), value :: missing 96 | type(c_ptr) :: out ! DMatrixHandle* 97 | end function 98 | end interface 99 | 100 | interface 101 | integer(c_int) function XGDMatrixNumRow_f(handle, out) & 102 | bind(c, name="XGDMatrixNumRow") 103 | use iso_c_binding, only: c_int, c_ptr, c_int64_t 104 | type(c_ptr), value :: handle ! DMatrixHandle 105 | integer(c_int64_t) :: out ! bst_ulong* 106 | end function 107 | end interface 108 | 109 | interface 110 | integer(c_int) function XGDMatrixNumCol_f(handle, out) & 111 | bind(c, name="XGDMatrixNumCol") 112 | use iso_c_binding, only: c_int, c_ptr, c_int64_t 113 | type(c_ptr), value :: handle ! DMatrixHandle 114 | integer(c_int64_t) :: out ! bst_ulong* 115 | end function 116 | end interface 117 | 118 | interface 119 | integer(c_int) function XGBoosterFree_f(handle) bind(c, name="XGBoosterFree") 120 | use iso_c_binding, only: c_int, c_ptr 121 | type(c_ptr), value :: handle ! BoosterHandle 122 | end function 123 | end interface 124 | 125 | contains 126 | integer(kind=c_int) function XGBoosterLoadModel_f(handle, fname) result(rc) 127 | use iso_c_binding, only: c_int, c_char, c_ptr, c_null_char 128 | type(c_ptr) :: handle ! BoosterHandle 129 | character(len=*) :: fname 130 | character(len=:),allocatable :: cname 131 | ! starts here 132 | cname = trim(fname)//c_null_char 133 | rc = XGBoosterLoadModel_c(handle, cname) 134 | end function 135 | 136 | integer(kind=c_int) function XGBoosterSaveModel_f(handle, fname) result(rc) 137 | use iso_c_binding, only: c_int, c_char, c_ptr, c_null_char 138 | type(c_ptr) :: handle ! BoosterHandle 139 | character(len=*) :: fname 140 | character(len=:),allocatable :: cname 141 | ! starts here 142 | cname = trim(fname)//c_null_char 143 | rc = XGBoosterSaveModel_c(handle, cname) 144 | end function 145 | 146 | integer(kind=c_int) function XGDMatrixSaveBinary_f(handle, fname, silent) result(rc) 147 | use iso_c_binding, only: c_int, c_char, c_ptr, c_null_char 148 | type(c_ptr) :: handle ! DMatrixHandle 149 | character(len=*) :: fname 150 | integer(kind=c_int) :: silent 151 | character(len=:),allocatable :: cname 152 | ! starts here 153 | cname = trim(fname)//c_null_char 154 | rc = XGDMatrixSaveBinary_c(handle, cname, silent) 155 | end function 156 | 157 | integer(kind=c_int) function XGDMatrixCreateFromFile_f(fname, silent, handle) result(rc) 158 | use iso_c_binding, only: c_int, c_char, c_ptr, c_null_char 159 | character(len=*) :: fname 160 | integer(kind=c_int) :: silent 161 | type(c_ptr) :: handle ! DMatrixHandle 162 | character(len=:),allocatable :: cname 163 | ! starts here 164 | cname = trim(fname)//c_null_char 165 | rc = XGDMatrixCreateFromFile_c(cname, silent, handle) 166 | end function 167 | 168 | integer(kind=c_int) function XGBoosterPredictFromDMatrix_f(handle, dmat, c_json_config, out_shape, out_dim, prediction) result(rc) 169 | use iso_c_binding, only: c_int, c_char, c_ptr, c_int64_t, c_float, c_double 170 | type(c_ptr), value :: handle ! BoosterHandle 171 | type(c_ptr), value :: dmat ! DMatrixHandle 172 | character(len=*) :: c_json_config 173 | type(c_ptr) :: out_shape 174 | integer(c_int64_t) :: out_dim 175 | type(c_ptr) :: prediction ! prediction 176 | ! local variable 177 | character(len=:),allocatable :: cname 178 | ! starts here 179 | cname = trim(c_json_config)//c_null_char 180 | rc = XGBoosterPredictFromDMatrix_c(handle, dmat, cname, out_shape, out_dim, prediction) 181 | end function 182 | 183 | end module 184 | --------------------------------------------------------------------------------