diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..f1922e9 --- /dev/null +++ b/.clang-format @@ -0,0 +1,213 @@ +--- +Language: Cpp +# BasedOnStyle: Google +AccessModifierOffset: -1 +AlignAfterOpenBracket: Align +AlignArrayOfStructures: None +AlignConsecutiveMacros: None +AlignConsecutiveAssignments: None +AlignConsecutiveBitFields: None +AlignConsecutiveDeclarations: None +AlignEscapedNewlines: Left +AlignOperands: Align +AlignTrailingComments: true +AllowAllArgumentsOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortEnumsOnASingleLine: true +AllowShortBlocksOnASingleLine: Never +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: All +AllowShortLambdasOnASingleLine: Inline +AllowShortIfStatementsOnASingleLine: WithoutElse +AllowShortLoopsOnASingleLine: true +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: true +AlwaysBreakTemplateDeclarations: Yes +AttributeMacros: + - __capability +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterCaseLabel: false + AfterClass: false + AfterControlStatement: Never + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false + BeforeLambdaBody: false + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: None +BreakBeforeConceptDeclarations: true +BreakBeforeBraces: Attach +BreakBeforeInheritanceComma: false +BreakInheritanceList: BeforeColon +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeColon +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 100 +CommentPragmas: '^ IWYU pragma:' +QualifierAlignment: Leave +CompactNamespaces: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DeriveLineEnding: true +DerivePointerAlignment: true +DisableFormat: false +EmptyLineAfterAccessModifier: Never +EmptyLineBeforeAccessModifier: LogicalBlock +ExperimentalAutoDetectBinPacking: false +PackConstructorInitializers: NextLine +BasedOnStyle: '' +ConstructorInitializerAllOnOneLineOrOnePerLine: false +AllowAllConstructorInitializersOnNextLine: true +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IfMacros: + - KJ_IF_MAYBE +IncludeBlocks: Regroup +IncludeCategories: + - Regex: '^' + Priority: 2 + SortPriority: 0 + CaseSensitive: false + - Regex: '^<.*\.h>' + Priority: 1 + SortPriority: 0 + CaseSensitive: false + - Regex: '^<.*' + Priority: 2 + SortPriority: 0 + CaseSensitive: false + - Regex: '.*' + Priority: 3 + SortPriority: 0 + CaseSensitive: false +IncludeIsMainRegex: '([-_](test|unittest))?$' +IncludeIsMainSourceRegex: '' +IndentAccessModifiers: false +IndentCaseLabels: true +IndentCaseBlocks: false +IndentGotoLabels: true +IndentPPDirectives: None +IndentExternBlock: AfterExternBlock +IndentRequires: false +IndentWidth: 2 +IndentWrappedFunctionNames: false +InsertTrailingCommas: None +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: false +LambdaBodyIndentation: Signature +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBinPackProtocolList: Never +ObjCBlockIndentWidth: 2 +ObjCBreakBeforeNestedBlockParam: true +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 1 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 200 +PenaltyIndentedWhitespace: 0 +PointerAlignment: Left +PPIndentWidth: -1 +RawStringFormats: + - Language: Cpp + Delimiters: + - cc + - CC + - cpp + - Cpp + - CPP + - 'c++' + - 'C++' + CanonicalDelimiter: '' + BasedOnStyle: google + - Language: TextProto + Delimiters: + - pb + - PB + - proto + - PROTO + EnclosingFunctions: + - EqualsProto + - EquivToProto + - PARSE_PARTIAL_TEXT_PROTO + - PARSE_TEST_PROTO + - PARSE_TEXT_PROTO + - ParseTextOrDie + - ParseTextProtoOrDie + - ParseTestProto + - ParsePartialTestProto + CanonicalDelimiter: pb + BasedOnStyle: google +ReferenceAlignment: Pointer +ReflowComments: false +ShortNamespaceLines: 1 +SortIncludes: CaseSensitive +SortJavaStaticImport: Before +SortUsingDeclarations: true +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeCaseColon: false +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceAroundPointerQualifiers: Default +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyBlock: false +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 2 +SpacesInAngles: Never +SpacesInConditionalStatement: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInLineCommentPrefix: + Minimum: 1 + Maximum: -1 +SpacesInParentheses: false +SpacesInSquareBrackets: false +SpaceBeforeSquareBrackets: false +BitFieldColonSpacing: Both +Standard: Auto +StatementAttributeLikeMacros: + - Q_EMIT +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +TabWidth: 8 +UseCRLF: false +UseTab: Never +WhitespaceSensitiveMacros: + - STRINGIZE + - PP_STRINGIZE + - BOOST_PP_STRINGIZE + - NS_SWIFT_NAME + - CF_SWIFT_NAME diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index ed08691..2d30f9f 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -11,6 +11,7 @@ RUN apt-get update && \ apt-get install --yes --no-install-recommends \ build-essential \ ca-certificates \ + clang-format \ cmake \ curl \ g++-14 \ diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index c452d66..8644b84 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -14,7 +14,8 @@ "customizations": { "vscode": { "extensions": [ - "jakebecker.elixir-ls" + "jakebecker.elixir-ls", + "xaver.clang-format" ] } }, diff --git a/CHANGELOG.md b/CHANGELOG.md index 4aa4ef6..1219098 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,23 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## UNRELEASED + +### Added + +- `clang-format` command added to dev container Dockerfile. +- `.clang-format` file from `xgboost` Github repo itself added as the default formatting of C files in this repo. +- `xaver.clang-format"` vscode extension added to repo. + +### Updated + +- Formatting pass across all source and header files in `c/exgboost` directory - formatting change only no code changes. +- Formatting information added to `CHANGELOG.md`. + +### Removed + +- Nothing. + ## 0.10.2 ### Added diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 81c8531..20ce2d2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -356,11 +356,12 @@ Large-data tests can reveal memory issues, but they do not prove that no memory ## Pull Request Checklist - [ ] Tests pass: `mix test` -- [ ] Code formatted: `mix format` +- [ ] Code formatted, for Elixir use `mix format` and for C use `clang-format`. If you are developing using VSCode make + use of the extensions inside the supplied devcontainer and ensure you `formatOnSave`. - [ ] No compiler warnings: `mix compile --warnings-as-errors` - [ ] Added tests for new functionality - [ ] Added invalid-input and boundary tests for NIF changes -- [ ] Updated CHANGELOG.md +- [ ] Updated `CHANGELOG.md` - [ ] NIF changes validated with safety tests - [ ] Native code tested under AddressSanitizer or Valgrind where supported - [ ] No native addresses are exposed or reused across NIF calls diff --git a/Makefile b/Makefile index 2fd89e0..78aaf55 100644 --- a/Makefile +++ b/Makefile @@ -32,7 +32,7 @@ EXGBOOST_SO = $(PRIV_DIR)/libexgboost.so EXGBOOST_LIB_DIR = $(PRIV_DIR)/lib # Build flags -CFLAGS = -I$(EXGBOOST_DIR)/include -I$(XGBOOST_LIB_DIR)/include -I$(XGBOOST_DIR) $(if $(ERTS_INCLUDE_DIR),-I$(ERTS_INCLUDE_DIR)) -fPIC -O3 --verbose -shared -std=c11 +CFLAGS = -I$(EXGBOOST_DIR)/include -I$(XGBOOST_LIB_DIR)/include -I$(XGBOOST_DIR) $(if $(ERTS_INCLUDE_DIR),-I$(ERTS_INCLUDE_DIR)) -fPIC -O3 -shared -std=c11 C_SRCS = $(wildcard $(EXGBOOST_DIR)/src/*.c) $(wildcard $(EXGBOOST_DIR)/include/*.h) @@ -110,4 +110,4 @@ clean: rm -rf $(EXGBOOST_SO) rm -rf $(EXGBOOST_LIB_DIR) rm -rf $(XGBOOST_DIR) - rm -rf $(XGBOOST_LIB_DIR_FLAG) \ No newline at end of file + rm -rf $(XGBOOST_LIB_DIR_FLAG) diff --git a/c/exgboost/include/booster.h b/c/exgboost/include/booster.h index 086a7d6..88946a3 100644 --- a/c/exgboost/include/booster.h +++ b/c/exgboost/include/booster.h @@ -3,56 +3,30 @@ #include "utils.h" -ERL_NIF_TERM EXGBoosterCreate(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]); -ERL_NIF_TERM EXGBoosterBoostedRounds(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]); -ERL_NIF_TERM EXGBoosterSlice(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]); -ERL_NIF_TERM EXGBoosterSetParam(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]); -ERL_NIF_TERM EXGBoosterGetNumFeature(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]); -ERL_NIF_TERM EXGBoosterUpdateOneIter(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]); -ERL_NIF_TERM EXGBoosterBoostOneIter(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]); -ERL_NIF_TERM EXGBoosterEvalOneIter(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]); -ERL_NIF_TERM EXGBoosterGetAttrNames(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]); -ERL_NIF_TERM EXGBoosterGetAttr(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]); -ERL_NIF_TERM EXGBoosterSetAttr(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]); -ERL_NIF_TERM EXGBoosterSetStrFeatureInfo(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]); -ERL_NIF_TERM EXGBoosterGetStrFeatureInfo(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]); -ERL_NIF_TERM EXGBoosterFeatureScore(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]); -ERL_NIF_TERM EXGBoosterPredictFromDMatrix(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]); -ERL_NIF_TERM EXGBoosterPredictFromDense(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]); -ERL_NIF_TERM EXGBoosterPredictFromCSR(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]); -ERL_NIF_TERM EXGBoosterLoadModel(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]); -ERL_NIF_TERM EXGBoosterSaveModel(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]); -ERL_NIF_TERM EXGBoosterSerializeToBuffer(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]); -ERL_NIF_TERM EXGBoosterDeserializeFromBuffer(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]); -ERL_NIF_TERM EXGBoosterLoadModelFromBuffer(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]); -ERL_NIF_TERM EXGBoosterSaveModelToBuffer(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]); -ERL_NIF_TERM EXGBoosterSaveJsonConfig(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]); -ERL_NIF_TERM EXGBoosterLoadJsonConfig(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]); -ERL_NIF_TERM EXGBoosterDumpModelEx(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]); +ERL_NIF_TERM EXGBoosterCreate(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); +ERL_NIF_TERM EXGBoosterBoostedRounds(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); +ERL_NIF_TERM EXGBoosterSlice(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); +ERL_NIF_TERM EXGBoosterSetParam(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); +ERL_NIF_TERM EXGBoosterGetNumFeature(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); +ERL_NIF_TERM EXGBoosterUpdateOneIter(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); +ERL_NIF_TERM EXGBoosterBoostOneIter(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); +ERL_NIF_TERM EXGBoosterEvalOneIter(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); +ERL_NIF_TERM EXGBoosterGetAttrNames(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); +ERL_NIF_TERM EXGBoosterGetAttr(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); +ERL_NIF_TERM EXGBoosterSetAttr(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); +ERL_NIF_TERM EXGBoosterSetStrFeatureInfo(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); +ERL_NIF_TERM EXGBoosterGetStrFeatureInfo(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); +ERL_NIF_TERM EXGBoosterFeatureScore(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); +ERL_NIF_TERM EXGBoosterPredictFromDMatrix(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); +ERL_NIF_TERM EXGBoosterPredictFromDense(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); +ERL_NIF_TERM EXGBoosterPredictFromCSR(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); +ERL_NIF_TERM EXGBoosterLoadModel(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); +ERL_NIF_TERM EXGBoosterSaveModel(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); +ERL_NIF_TERM EXGBoosterSerializeToBuffer(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); +ERL_NIF_TERM EXGBoosterDeserializeFromBuffer(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); +ERL_NIF_TERM EXGBoosterLoadModelFromBuffer(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); +ERL_NIF_TERM EXGBoosterSaveModelToBuffer(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); +ERL_NIF_TERM EXGBoosterSaveJsonConfig(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); +ERL_NIF_TERM EXGBoosterLoadJsonConfig(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); +ERL_NIF_TERM EXGBoosterDumpModelEx(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); #endif diff --git a/c/exgboost/include/dmatrix.h b/c/exgboost/include/dmatrix.h index 1efc6da..faefc8a 100644 --- a/c/exgboost/include/dmatrix.h +++ b/c/exgboost/include/dmatrix.h @@ -3,50 +3,32 @@ #include "utils.h" -ERL_NIF_TERM EXGDMatrixCreateFromFile(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]); - -ERL_NIF_TERM EXGDMatrixCreateFromURI(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]); - -ERL_NIF_TERM EXGDMatrixCreateFromMat(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]); - -ERL_NIF_TERM EXGDMatrixCreateFromSparse(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]); - -ERL_NIF_TERM EXGDMatrixCreateFromDense(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]); - -ERL_NIF_TERM EXGDMatrixGetStrFeatureInfo(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]); - -ERL_NIF_TERM EXGDMatrixSetStrFeatureInfo(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]); - -ERL_NIF_TERM EXGDMatrixNumRow(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]); - -ERL_NIF_TERM EXGDMatrixNumCol(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]); - -ERL_NIF_TERM EXGDMatrixNumNonMissing(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]); - -ERL_NIF_TERM EXGDMatrixSetInfoFromInterface(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]); -ERL_NIF_TERM EXGDMatrixSaveBinary(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]); -ERL_NIF_TERM EXGDMatrixGetFloatInfo(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]); -ERL_NIF_TERM EXGDMatrixGetUIntInfo(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]); -ERL_NIF_TERM EXGDMatrixGetDataAsCSR(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]); -ERL_NIF_TERM EXGDMatrixSliceDMatrix(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]); -ERL_NIF_TERM EXGProxyDMatrixCreate(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]); -ERL_NIF_TERM EXGDMatrixGetQuantileCut(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]); +ERL_NIF_TERM EXGDMatrixCreateFromFile(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); + +ERL_NIF_TERM EXGDMatrixCreateFromURI(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); + +ERL_NIF_TERM EXGDMatrixCreateFromMat(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); + +ERL_NIF_TERM EXGDMatrixCreateFromSparse(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); + +ERL_NIF_TERM EXGDMatrixCreateFromDense(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); + +ERL_NIF_TERM EXGDMatrixGetStrFeatureInfo(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); + +ERL_NIF_TERM EXGDMatrixSetStrFeatureInfo(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); + +ERL_NIF_TERM EXGDMatrixNumRow(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); + +ERL_NIF_TERM EXGDMatrixNumCol(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); + +ERL_NIF_TERM EXGDMatrixNumNonMissing(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); + +ERL_NIF_TERM EXGDMatrixSetInfoFromInterface(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); +ERL_NIF_TERM EXGDMatrixSaveBinary(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); +ERL_NIF_TERM EXGDMatrixGetFloatInfo(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); +ERL_NIF_TERM EXGDMatrixGetUIntInfo(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); +ERL_NIF_TERM EXGDMatrixGetDataAsCSR(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); +ERL_NIF_TERM EXGDMatrixSliceDMatrix(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); +ERL_NIF_TERM EXGProxyDMatrixCreate(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); +ERL_NIF_TERM EXGDMatrixGetQuantileCut(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); #endif \ No newline at end of file diff --git a/c/exgboost/include/exgboost.h b/c/exgboost/include/exgboost.h index 014df9f..eb3cfdb 100644 --- a/c/exgboost/include/exgboost.h +++ b/c/exgboost/include/exgboost.h @@ -1,8 +1,8 @@ #ifndef EXGBOOST_H #define EXGBOOST_H +#include "booster.h" #include "config.h" #include "dmatrix.h" -#include "booster.h" #endif \ No newline at end of file diff --git a/c/exgboost/include/utils.h b/c/exgboost/include/utils.h index 5141cd9..92c4a39 100644 --- a/c/exgboost/include/utils.h +++ b/c/exgboost/include/utils.h @@ -3,11 +3,11 @@ #include #include +#include #include #include #include #include -#include ErlNifResourceType *DMatrix_RESOURCE_TYPE; ErlNifResourceType *Booster_RESOURCE_TYPE; @@ -28,8 +28,7 @@ ERL_NIF_TERM ok_atom(ErlNifEnv *env); ERL_NIF_TERM exg_ok(ErlNifEnv *env, ERL_NIF_TERM term); -ERL_NIF_TERM exg_get_int_size(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]); +ERL_NIF_TERM exg_get_int_size(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]); // Argument helpers @@ -37,37 +36,28 @@ int exg_get_string(ErlNifEnv *env, ERL_NIF_TERM term, char **var); int exg_get_list(ErlNifEnv *env, ERL_NIF_TERM term, double **out); -int exg_get_string_list(ErlNifEnv *env, ERL_NIF_TERM term, char ***out, - unsigned *len); -int exg_get_dmatrix_list(ErlNifEnv *env, ERL_NIF_TERM term, - DMatrixHandle **dmats, unsigned *len); +int exg_get_string_list(ErlNifEnv *env, ERL_NIF_TERM term, char ***out, unsigned *len); +int exg_get_dmatrix_list(ErlNifEnv *env, ERL_NIF_TERM term, DMatrixHandle **dmats, unsigned *len); void exg_free_string_list(char **items, unsigned len); void exg_free_dmatrix_list(DMatrixHandle *dmats); // Array Interface helper - extracts components from tuple {binary, typestr, shape, readonly} -int exg_get_array_interface_tuple(ErlNifEnv *env, ERL_NIF_TERM tuple_term, - ERL_NIF_TERM *binary_out, - ERL_NIF_TERM *typestr_out, - ERL_NIF_TERM *shape_out, - ERL_NIF_TERM *readonly_out, - const char **error_msg); +int exg_get_array_interface_tuple(ErlNifEnv *env, ERL_NIF_TERM tuple_term, ERL_NIF_TERM *binary_out, + ERL_NIF_TERM *typestr_out, ERL_NIF_TERM *shape_out, + ERL_NIF_TERM *readonly_out, const char **error_msg); // Array Interface helper - builds JSON from components with fresh address int exg_build_array_interface_json(ErlNifEnv *env, ERL_NIF_TERM binary_term, - ERL_NIF_TERM typestr_term, ERL_NIF_TERM shape_term, - ERL_NIF_TERM readonly_term, char **json_out, - const char **error_msg); + ERL_NIF_TERM typestr_term, ERL_NIF_TERM shape_term, + ERL_NIF_TERM readonly_term, char **json_out, + const char **error_msg); // Array Interface helper - builds map from components -int exg_make_array_interface_map( - ErlNifEnv *env, - ERL_NIF_TERM binary_term, - ERL_NIF_TERM typestr_term, - ERL_NIF_TERM shape_term, - ERL_NIF_TERM *out_map -); +int exg_make_array_interface_map(ErlNifEnv *env, ERL_NIF_TERM binary_term, + ERL_NIF_TERM typestr_term, ERL_NIF_TERM shape_term, + ERL_NIF_TERM *out_map); int exg_parse_typestr(const char *typestr, size_t *element_size_out, const char **error_msg); diff --git a/c/exgboost/src/booster.c b/c/exgboost/src/booster.c index 17f9864..d401d49 100644 --- a/c/exgboost/src/booster.c +++ b/c/exgboost/src/booster.c @@ -1,11 +1,10 @@ #include "booster.h" + #include -static ERL_NIF_TERM make_Booster_resource(ErlNifEnv *env, - BoosterHandle handle) { +static ERL_NIF_TERM make_Booster_resource(ErlNifEnv *env, BoosterHandle handle) { ERL_NIF_TERM ret = -1; - BoosterHandle **resource = - enif_alloc_resource(Booster_RESOURCE_TYPE, sizeof(BoosterHandle *)); + BoosterHandle **resource = enif_alloc_resource(Booster_RESOURCE_TYPE, sizeof(BoosterHandle *)); if (resource != NULL) { *resource = handle; // BEAM resource now owns the handle and releases it in resource cleanup. @@ -17,8 +16,7 @@ static ERL_NIF_TERM make_Booster_resource(ErlNifEnv *env, return ret; } -ERL_NIF_TERM EXGBoosterCreate(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { +ERL_NIF_TERM EXGBoosterCreate(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { DMatrixHandle *dmats = NULL; ERL_NIF_TERM ret = -1; int result = -1; @@ -56,8 +54,7 @@ ERL_NIF_TERM EXGBoosterCreate(ErlNifEnv *env, int argc, return ret; } -ERL_NIF_TERM EXGBoosterSlice(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { +ERL_NIF_TERM EXGBoosterSlice(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { BoosterHandle in_booster; BoosterHandle out_booster; BoosterHandle **resource = NULL; @@ -70,8 +67,7 @@ ERL_NIF_TERM EXGBoosterSlice(ErlNifEnv *env, int argc, ret = exg_error(env, "Wrong number of arguments"); goto END; } - if (!enif_get_resource(env, argv[0], Booster_RESOURCE_TYPE, - (void *)&(resource))) { + if (!enif_get_resource(env, argv[0], Booster_RESOURCE_TYPE, (void *)&(resource))) { ret = exg_error(env, "Invalid Booster"); goto END; } @@ -88,8 +84,7 @@ ERL_NIF_TERM EXGBoosterSlice(ErlNifEnv *env, int argc, ret = exg_error(env, "Invalid step"); goto END; } - result = - XGBoosterSlice(in_booster, begin_layer, end_layer, step, &out_booster); + result = XGBoosterSlice(in_booster, begin_layer, end_layer, step, &out_booster); if (result == 0) { ret = make_Booster_resource(env, out_booster); } else { @@ -99,8 +94,7 @@ ERL_NIF_TERM EXGBoosterSlice(ErlNifEnv *env, int argc, return ret; } -ERL_NIF_TERM EXGBoosterBoostedRounds(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { +ERL_NIF_TERM EXGBoosterBoostedRounds(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { BoosterHandle booster; BoosterHandle **resource = NULL; int rounds; @@ -110,8 +104,7 @@ ERL_NIF_TERM EXGBoosterBoostedRounds(ErlNifEnv *env, int argc, ret = exg_error(env, "Wrong number of arguments"); goto END; } - if (!enif_get_resource(env, argv[0], Booster_RESOURCE_TYPE, - (void *)&(resource))) { + if (!enif_get_resource(env, argv[0], Booster_RESOURCE_TYPE, (void *)&(resource))) { ret = exg_error(env, "Invalid Booster"); goto END; } @@ -126,8 +119,7 @@ ERL_NIF_TERM EXGBoosterBoostedRounds(ErlNifEnv *env, int argc, return ret; } -ERL_NIF_TERM EXGBoosterSetParam(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { +ERL_NIF_TERM EXGBoosterSetParam(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { BoosterHandle booster; BoosterHandle **resource = NULL; char *name = NULL; @@ -138,8 +130,7 @@ ERL_NIF_TERM EXGBoosterSetParam(ErlNifEnv *env, int argc, ret = exg_error(env, "Wrong number of arguments"); goto END; } - if (!enif_get_resource(env, argv[0], Booster_RESOURCE_TYPE, - (void *)&(resource))) { + if (!enif_get_resource(env, argv[0], Booster_RESOURCE_TYPE, (void *)&(resource))) { ret = exg_error(env, "Invalid Booster"); goto END; } @@ -169,8 +160,7 @@ ERL_NIF_TERM EXGBoosterSetParam(ErlNifEnv *env, int argc, return ret; } -ERL_NIF_TERM EXGBoosterGetNumFeature(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { +ERL_NIF_TERM EXGBoosterGetNumFeature(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { BoosterHandle booster; BoosterHandle **resource = NULL; bst_ulong num_feature; @@ -180,8 +170,7 @@ ERL_NIF_TERM EXGBoosterGetNumFeature(ErlNifEnv *env, int argc, ret = exg_error(env, "Wrong number of arguments"); goto END; } - if (!enif_get_resource(env, argv[0], Booster_RESOURCE_TYPE, - (void *)&(resource))) { + if (!enif_get_resource(env, argv[0], Booster_RESOURCE_TYPE, (void *)&(resource))) { ret = exg_error(env, "Invalid Booster"); goto END; } @@ -196,8 +185,7 @@ ERL_NIF_TERM EXGBoosterGetNumFeature(ErlNifEnv *env, int argc, return ret; } -ERL_NIF_TERM EXGBoosterUpdateOneIter(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { +ERL_NIF_TERM EXGBoosterUpdateOneIter(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { BoosterHandle booster; BoosterHandle **booster_resource = NULL; DMatrixHandle dtrain; @@ -209,14 +197,12 @@ ERL_NIF_TERM EXGBoosterUpdateOneIter(ErlNifEnv *env, int argc, ret = exg_error(env, "Wrong number of arguments"); goto END; } - if (!enif_get_resource(env, argv[0], Booster_RESOURCE_TYPE, - (void *)&(booster_resource))) { + if (!enif_get_resource(env, argv[0], Booster_RESOURCE_TYPE, (void *)&(booster_resource))) { ret = exg_error(env, "Invalid Booster"); goto END; } booster = *booster_resource; - if (!enif_get_resource(env, argv[1], DMatrix_RESOURCE_TYPE, - (void *)&(dtrain_resource))) { + if (!enif_get_resource(env, argv[1], DMatrix_RESOURCE_TYPE, (void *)&(dtrain_resource))) { ret = exg_error(env, "Invalid DMatrix"); goto END; } @@ -234,8 +220,7 @@ ERL_NIF_TERM EXGBoosterUpdateOneIter(ErlNifEnv *env, int argc, END: return ret; } -ERL_NIF_TERM EXGBoosterBoostOneIter(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { +ERL_NIF_TERM EXGBoosterBoostOneIter(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { ErlNifBinary grad_bin; ErlNifBinary hess_bin; BoosterHandle booster; @@ -253,14 +238,12 @@ ERL_NIF_TERM EXGBoosterBoostOneIter(ErlNifEnv *env, int argc, ret = exg_error(env, "Wrong number of arguments"); goto END; } - if (!enif_get_resource(env, argv[0], Booster_RESOURCE_TYPE, - (void *)&(booster_resource))) { + if (!enif_get_resource(env, argv[0], Booster_RESOURCE_TYPE, (void *)&(booster_resource))) { ret = exg_error(env, "Invalid Booster"); goto END; } booster = *booster_resource; - if (!enif_get_resource(env, argv[1], DMatrix_RESOURCE_TYPE, - (void *)&(dtrain_resource))) { + if (!enif_get_resource(env, argv[1], DMatrix_RESOURCE_TYPE, (void *)&(dtrain_resource))) { ret = exg_error(env, "Invalid DMatrix"); goto END; } @@ -281,8 +264,7 @@ ERL_NIF_TERM EXGBoosterBoostOneIter(ErlNifEnv *env, int argc, ret = exg_error(env, "Grad and Hess must have the same length"); goto END; } - result = - XGBoosterBoostOneIter(booster, dtrain, grad, hess, (bst_ulong)grad_len); + result = XGBoosterBoostOneIter(booster, dtrain, grad, hess, (bst_ulong)grad_len); if (result == 0) { ret = ok_atom(env); } else { @@ -292,8 +274,7 @@ ERL_NIF_TERM EXGBoosterBoostOneIter(ErlNifEnv *env, int argc, return ret; } -ERL_NIF_TERM EXGBoosterEvalOneIter(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { +ERL_NIF_TERM EXGBoosterEvalOneIter(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { BoosterHandle booster; BoosterHandle **booster_resource = NULL; DMatrixHandle *dmats = NULL; @@ -308,8 +289,7 @@ ERL_NIF_TERM EXGBoosterEvalOneIter(ErlNifEnv *env, int argc, ret = exg_error(env, "Wrong number of arguments"); goto END; } - if (!enif_get_resource(env, argv[0], Booster_RESOURCE_TYPE, - (void *)&(booster_resource))) { + if (!enif_get_resource(env, argv[0], Booster_RESOURCE_TYPE, (void *)&(booster_resource))) { ret = exg_error(env, "Invalid Booster"); goto END; } @@ -330,8 +310,8 @@ ERL_NIF_TERM EXGBoosterEvalOneIter(ErlNifEnv *env, int argc, ret = exg_error(env, "dmats and evnames must have the same length"); goto END; } - result = XGBoosterEvalOneIter(booster, iter, dmats, (const char **)evnames, - (bst_ulong)num_dmats, &out); + result = XGBoosterEvalOneIter(booster, iter, dmats, (const char **)evnames, (bst_ulong)num_dmats, + &out); if (result == 0) { ret = exg_ok(env, enif_make_string(env, out, ERL_NIF_LATIN1)); } else { @@ -344,8 +324,7 @@ ERL_NIF_TERM EXGBoosterEvalOneIter(ErlNifEnv *env, int argc, return ret; } -ERL_NIF_TERM EXGBoosterGetAttr(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { +ERL_NIF_TERM EXGBoosterGetAttr(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { BoosterHandle booster; BoosterHandle **booster_resource = NULL; char *key = NULL; @@ -357,8 +336,7 @@ ERL_NIF_TERM EXGBoosterGetAttr(ErlNifEnv *env, int argc, ret = exg_error(env, "Wrong number of arguments"); goto END; } - if (!enif_get_resource(env, argv[0], Booster_RESOURCE_TYPE, - (void *)&(booster_resource))) { + if (!enif_get_resource(env, argv[0], Booster_RESOURCE_TYPE, (void *)&(booster_resource))) { ret = exg_error(env, "Invalid Booster"); goto END; } @@ -384,8 +362,7 @@ ERL_NIF_TERM EXGBoosterGetAttr(ErlNifEnv *env, int argc, return ret; } -ERL_NIF_TERM EXGBoosterSetAttr(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { +ERL_NIF_TERM EXGBoosterSetAttr(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { BoosterHandle booster; BoosterHandle **booster_resource = NULL; char *key = NULL; @@ -397,8 +374,7 @@ ERL_NIF_TERM EXGBoosterSetAttr(ErlNifEnv *env, int argc, ret = exg_error(env, "Wrong number of arguments"); goto END; } - if (!enif_get_resource(env, argv[0], Booster_RESOURCE_TYPE, - (void *)&(booster_resource))) { + if (!enif_get_resource(env, argv[0], Booster_RESOURCE_TYPE, (void *)&(booster_resource))) { ret = exg_error(env, "Invalid Booster"); goto END; } @@ -441,8 +417,7 @@ ERL_NIF_TERM EXGBoosterSetAttr(ErlNifEnv *env, int argc, return ret; } -ERL_NIF_TERM EXGBoosterGetAttrNames(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { +ERL_NIF_TERM EXGBoosterGetAttrNames(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { BoosterHandle booster; BoosterHandle **booster_resource = NULL; const char **out = NULL; @@ -455,8 +430,7 @@ ERL_NIF_TERM EXGBoosterGetAttrNames(ErlNifEnv *env, int argc, goto END; } - if (!enif_get_resource(env, argv[0], Booster_RESOURCE_TYPE, - (void *)&(booster_resource))) { + if (!enif_get_resource(env, argv[0], Booster_RESOURCE_TYPE, (void *)&(booster_resource))) { ret = exg_error(env, "Invalid Booster"); goto END; } @@ -478,23 +452,12 @@ ERL_NIF_TERM EXGBoosterGetAttrNames(ErlNifEnv *env, int argc, } for (bst_ulong i = 0; i < out_len; ++i) { - arr[i] = - enif_make_string( - env, - out[i], - ERL_NIF_LATIN1 - ); + arr[i] = enif_make_string(env, out[i], ERL_NIF_LATIN1); } } - ERL_NIF_TERM list = - out_len == 0 - ? enif_make_list(env, 0) - : enif_make_list_from_array( - env, - arr, - (unsigned)out_len - ); + ERL_NIF_TERM list = out_len == 0 ? enif_make_list(env, 0) + : enif_make_list_from_array(env, arr, (unsigned)out_len); ret = exg_ok(env, list); } else { @@ -509,8 +472,7 @@ ERL_NIF_TERM EXGBoosterGetAttrNames(ErlNifEnv *env, int argc, return ret; } -ERL_NIF_TERM EXGBoosterSetStrFeatureInfo(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { +ERL_NIF_TERM EXGBoosterSetStrFeatureInfo(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { BoosterHandle handle; BoosterHandle **resource = NULL; char **features = NULL; @@ -522,8 +484,7 @@ ERL_NIF_TERM EXGBoosterSetStrFeatureInfo(ErlNifEnv *env, int argc, ret = exg_error(env, "Wrong number of arguments"); goto END; } - if (!enif_get_resource(env, argv[0], Booster_RESOURCE_TYPE, - (void *)&resource)) { + if (!enif_get_resource(env, argv[0], Booster_RESOURCE_TYPE, (void *)&resource)) { ret = exg_error(env, "Booster must be a resource"); goto END; } @@ -535,14 +496,12 @@ ERL_NIF_TERM EXGBoosterSetStrFeatureInfo(ErlNifEnv *env, int argc, ret = exg_error(env, "Features must be a list"); goto END; } - if (strcmp(field, "feature_type") != 0 && - strcmp(field, "feature_name") != 0) { + if (strcmp(field, "feature_type") != 0 && strcmp(field, "feature_name") != 0) { ret = exg_error(env, "Field must be in ['feature_type', 'feature_name']"); goto END; } handle = *resource; - result = XGBoosterSetStrFeatureInfo(handle, field, (const char **)features, - num_features); + result = XGBoosterSetStrFeatureInfo(handle, field, (const char **)features, num_features); if (result == 0) { ret = ok_atom(env); } else { @@ -557,8 +516,7 @@ ERL_NIF_TERM EXGBoosterSetStrFeatureInfo(ErlNifEnv *env, int argc, } return ret; } -ERL_NIF_TERM EXGBoosterGetStrFeatureInfo(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { +ERL_NIF_TERM EXGBoosterGetStrFeatureInfo(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { BoosterHandle handle; BoosterHandle **resource = NULL; char const **c_out_features = NULL; @@ -573,8 +531,7 @@ ERL_NIF_TERM EXGBoosterGetStrFeatureInfo(ErlNifEnv *env, int argc, goto END; } - if (!enif_get_resource(env, argv[0], Booster_RESOURCE_TYPE, - (void *)&resource)) { + if (!enif_get_resource(env, argv[0], Booster_RESOURCE_TYPE, (void *)&resource)) { ret = exg_error(env, "Booster must be a resource"); goto END; } @@ -584,8 +541,7 @@ ERL_NIF_TERM EXGBoosterGetStrFeatureInfo(ErlNifEnv *env, int argc, goto END; } - if (strcmp(field, "feature_type") != 0 && - strcmp(field, "feature_name") != 0) { + if (strcmp(field, "feature_type") != 0 && strcmp(field, "feature_name") != 0) { ret = exg_error(env, "Field must be in ['feature_type', 'feature_name']"); goto END; } @@ -594,8 +550,7 @@ ERL_NIF_TERM EXGBoosterGetStrFeatureInfo(ErlNifEnv *env, int argc, result = XGBoosterGetStrFeatureInfo(handle, field, &out_len, &c_out_features); if (result == 0) { - if (out_len > UINT_MAX || - out_len > SIZE_MAX / sizeof(*arr)) { + if (out_len > UINT_MAX || out_len > SIZE_MAX / sizeof(*arr)) { ret = exg_error(env, "Result is too large"); goto END; } @@ -609,23 +564,12 @@ ERL_NIF_TERM EXGBoosterGetStrFeatureInfo(ErlNifEnv *env, int argc, } for (bst_ulong i = 0; i < out_len; ++i) { - arr[i] = - enif_make_string( - env, - c_out_features[i], - ERL_NIF_LATIN1 - ); + arr[i] = enif_make_string(env, c_out_features[i], ERL_NIF_LATIN1); } } - ERL_NIF_TERM list = - out_len == 0 - ? enif_make_list(env, 0) - : enif_make_list_from_array( - env, - arr, - (unsigned)out_len - ); + ERL_NIF_TERM list = out_len == 0 ? enif_make_list(env, 0) + : enif_make_list_from_array(env, arr, (unsigned)out_len); ret = exg_ok(env, list); } else { @@ -641,11 +585,7 @@ ERL_NIF_TERM EXGBoosterGetStrFeatureInfo(ErlNifEnv *env, int argc, return ret; } -ERL_NIF_TERM EXGBoosterFeatureScore( - ErlNifEnv *env, - int argc, - const ERL_NIF_TERM argv[] -) { +ERL_NIF_TERM EXGBoosterFeatureScore(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { BoosterHandle booster; BoosterHandle **booster_resource = NULL; char *config = NULL; @@ -668,11 +608,7 @@ ERL_NIF_TERM EXGBoosterFeatureScore( goto END; } - if (!enif_get_resource( - env, - argv[0], - Booster_RESOURCE_TYPE, - (void **)&booster_resource)) { + if (!enif_get_resource(env, argv[0], Booster_RESOURCE_TYPE, (void **)&booster_resource)) { ret = exg_error(env, "Invalid Booster"); goto END; } @@ -684,16 +620,8 @@ ERL_NIF_TERM EXGBoosterFeatureScore( booster = *booster_resource; - result = - XGBoosterFeatureScore( - booster, - config, - &out_n_features, - &out_features, - &out_dim, - &out_shape, - &out_scores - ); + result = XGBoosterFeatureScore(booster, config, &out_n_features, &out_features, &out_dim, + &out_shape, &out_scores); if (result != 0) { ret = exg_error(env, XGBGetLastError()); @@ -787,10 +715,7 @@ ERL_NIF_TERM EXGBoosterFeatureScore( goto END; } - feature_terms = - enif_alloc( - (size_t)out_n_features * sizeof(*feature_terms) - ); + feature_terms = enif_alloc((size_t)out_n_features * sizeof(*feature_terms)); if (feature_terms == NULL) { ret = exg_error(env, "Failed to allocate feature names"); @@ -803,12 +728,7 @@ ERL_NIF_TERM EXGBoosterFeatureScore( goto END; } - feature_terms[i] = - enif_make_string( - env, - out_features[i], - ERL_NIF_LATIN1 - ); + feature_terms[i] = enif_make_string(env, out_features[i], ERL_NIF_LATIN1); } } @@ -820,8 +740,7 @@ ERL_NIF_TERM EXGBoosterFeatureScore( goto END; } - shape_terms = - enif_alloc((size_t)out_dim * sizeof(*shape_terms)); + shape_terms = enif_alloc((size_t)out_dim * sizeof(*shape_terms)); if (shape_terms == NULL) { ret = exg_error(env, "Failed to allocate feature-score shape"); @@ -829,11 +748,7 @@ ERL_NIF_TERM EXGBoosterFeatureScore( } for (bst_ulong i = 0; i < out_dim; ++i) { - shape_terms[i] = - enif_make_uint64( - env, - (ErlNifUInt64)out_shape[i] - ); + shape_terms[i] = enif_make_uint64(env, (ErlNifUInt64)out_shape[i]); } /* @@ -845,8 +760,7 @@ ERL_NIF_TERM EXGBoosterFeatureScore( goto END; } - score_terms = - enif_alloc(score_count * sizeof(*score_terms)); + score_terms = enif_alloc(score_count * sizeof(*score_terms)); if (score_terms == NULL) { ret = exg_error(env, "Failed to allocate feature scores"); @@ -854,46 +768,21 @@ ERL_NIF_TERM EXGBoosterFeatureScore( } for (size_t i = 0; i < score_count; ++i) { - score_terms[i] = - enif_make_double(env, out_scores[i]); + score_terms[i] = enif_make_double(env, out_scores[i]); } } ERL_NIF_TERM features = - out_n_features == 0 - ? enif_make_list(env, 0) - : enif_make_list_from_array( - env, - feature_terms, - (unsigned)out_n_features - ); - - ERL_NIF_TERM shape = - enif_make_tuple_from_array( - env, - shape_terms, - (unsigned)out_dim - ); - - ERL_NIF_TERM scores = - score_count == 0 - ? enif_make_list(env, 0) - : enif_make_list_from_array( - env, - score_terms, - (unsigned)score_count - ); - - ret = - exg_ok( - env, - enif_make_tuple3( - env, - features, - shape, - scores - ) - ); + out_n_features == 0 ? enif_make_list(env, 0) + : enif_make_list_from_array(env, feature_terms, (unsigned)out_n_features); + + ERL_NIF_TERM shape = enif_make_tuple_from_array(env, shape_terms, (unsigned)out_dim); + + ERL_NIF_TERM scores = score_count == 0 + ? enif_make_list(env, 0) + : enif_make_list_from_array(env, score_terms, (unsigned)score_count); + + ret = exg_ok(env, enif_make_tuple3(env, features, shape, scores)); END: if (feature_terms != NULL) { @@ -915,12 +804,8 @@ ERL_NIF_TERM EXGBoosterFeatureScore( return ret; } -static ERL_NIF_TERM collect_prediction_results( - ErlNifEnv *env, - const bst_ulong *out_shape, - bst_ulong out_dim, - const float *out_result -) { +static ERL_NIF_TERM collect_prediction_results(ErlNifEnv *env, const bst_ulong *out_shape, + bst_ulong out_dim, const float *out_result) { ERL_NIF_TERM ret = 0; ERL_NIF_TERM *shape_terms = NULL; ERL_NIF_TERM *result_terms = NULL; @@ -937,13 +822,11 @@ static ERL_NIF_TERM collect_prediction_results( /* * enif_make_tuple_from_array() takes an unsigned count. */ - if (out_dim > UINT_MAX || - out_dim > SIZE_MAX / sizeof(*shape_terms)) { + if (out_dim > UINT_MAX || out_dim > SIZE_MAX / sizeof(*shape_terms)) { return exg_error(env, "Prediction dimension is too large"); } - shape_terms = - enif_alloc((size_t)out_dim * sizeof(*shape_terms)); + shape_terms = enif_alloc((size_t)out_dim * sizeof(*shape_terms)); if (shape_terms == NULL) { return exg_error(env, "Failed to allocate prediction shape"); @@ -966,15 +849,13 @@ static ERL_NIF_TERM collect_prediction_results( result_len *= dim; - shape_terms[i] = - enif_make_uint64(env, (ErlNifUInt64)dim_arg); + shape_terms[i] = enif_make_uint64(env, (ErlNifUInt64)dim_arg); } /* * enif_make_list_from_array() also takes an unsigned count. */ - if (result_len > UINT_MAX || - result_len > SIZE_MAX / sizeof(*result_terms)) { + if (result_len > UINT_MAX || result_len > SIZE_MAX / sizeof(*result_terms)) { ret = exg_error(env, "Prediction result is too large"); goto END; } @@ -985,8 +866,7 @@ static ERL_NIF_TERM collect_prediction_results( } if (result_len != 0) { - result_terms = - enif_alloc(result_len * sizeof(*result_terms)); + result_terms = enif_alloc(result_len * sizeof(*result_terms)); if (result_terms == NULL) { ret = exg_error(env, "Failed to allocate prediction result"); @@ -994,32 +874,17 @@ static ERL_NIF_TERM collect_prediction_results( } for (size_t i = 0; i < result_len; ++i) { - result_terms[i] = - enif_make_double(env, out_result[i]); + result_terms[i] = enif_make_double(env, out_result[i]); } } - ERL_NIF_TERM shape = - enif_make_tuple_from_array( - env, - shape_terms, - (unsigned)out_dim - ); - - ERL_NIF_TERM results = - result_len == 0 - ? enif_make_list(env, 0) - : enif_make_list_from_array( - env, - result_terms, - (unsigned)result_len - ); - - ret = - exg_ok( - env, - enif_make_tuple2(env, shape, results) - ); + ERL_NIF_TERM shape = enif_make_tuple_from_array(env, shape_terms, (unsigned)out_dim); + + ERL_NIF_TERM results = result_len == 0 + ? enif_make_list(env, 0) + : enif_make_list_from_array(env, result_terms, (unsigned)result_len); + + ret = exg_ok(env, enif_make_tuple2(env, shape, results)); END: if (shape_terms != NULL) { @@ -1033,8 +898,7 @@ static ERL_NIF_TERM collect_prediction_results( return ret; } -ERL_NIF_TERM EXGBoosterPredictFromDMatrix(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { +ERL_NIF_TERM EXGBoosterPredictFromDMatrix(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { BoosterHandle booster; BoosterHandle **booster_resource = NULL; DMatrixHandle dmatrix; @@ -1050,13 +914,11 @@ ERL_NIF_TERM EXGBoosterPredictFromDMatrix(ErlNifEnv *env, int argc, ret = exg_error(env, "Wrong number of arguments"); goto END; } - if (!enif_get_resource(env, argv[0], Booster_RESOURCE_TYPE, - (void *)&(booster_resource))) { + if (!enif_get_resource(env, argv[0], Booster_RESOURCE_TYPE, (void *)&(booster_resource))) { ret = exg_error(env, "Invalid Booster"); goto END; } - if (!enif_get_resource(env, argv[1], DMatrix_RESOURCE_TYPE, - (void *)&(dmatrix_resource))) { + if (!enif_get_resource(env, argv[1], DMatrix_RESOURCE_TYPE, (void *)&(dmatrix_resource))) { ret = exg_error(env, "Invalid DMatrix"); goto END; } @@ -1066,8 +928,7 @@ ERL_NIF_TERM EXGBoosterPredictFromDMatrix(ErlNifEnv *env, int argc, } booster = *booster_resource; dmatrix = *dmatrix_resource; - result = XGBoosterPredictFromDMatrix(booster, dmatrix, config, &out_shape, - &out_dim, &out_result); + result = XGBoosterPredictFromDMatrix(booster, dmatrix, config, &out_shape, &out_dim, &out_result); if (result == 0) { ret = collect_prediction_results(env, out_shape, out_dim, out_result); } else { @@ -1080,8 +941,7 @@ ERL_NIF_TERM EXGBoosterPredictFromDMatrix(ErlNifEnv *env, int argc, return ret; } -ERL_NIF_TERM EXGBoosterPredictFromDense(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { +ERL_NIF_TERM EXGBoosterPredictFromDense(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { BoosterHandle booster; BoosterHandle **booster_resource = NULL; DMatrixHandle proxy; @@ -1100,14 +960,14 @@ ERL_NIF_TERM EXGBoosterPredictFromDense(ErlNifEnv *env, int argc, goto END; } - if (!enif_get_resource(env, argv[0], Booster_RESOURCE_TYPE, - (void *)&(booster_resource))) { + if (!enif_get_resource(env, argv[0], Booster_RESOURCE_TYPE, (void *)&(booster_resource))) { ret = exg_error(env, "Invalid Booster"); goto END; } // Build ArrayInterface JSON from components: (binary, typestr, shape, readonly) - if (!exg_build_array_interface_json(env, argv[1], argv[2], argv[3], argv[4], &values, &error_msg)) { + if (!exg_build_array_interface_json(env, argv[1], argv[2], argv[3], argv[4], &values, + &error_msg)) { ret = exg_error(env, error_msg ? error_msg : "Failed to extract ArrayInterface"); goto END; } @@ -1117,15 +977,14 @@ ERL_NIF_TERM EXGBoosterPredictFromDense(ErlNifEnv *env, int argc, goto END; } - if (!enif_get_resource(env, argv[6], DMatrix_RESOURCE_TYPE, - (void *)&(proxy_resource))) { + if (!enif_get_resource(env, argv[6], DMatrix_RESOURCE_TYPE, (void *)&(proxy_resource))) { proxy = NULL; } else { proxy = *proxy_resource; } booster = *booster_resource; - result = XGBoosterPredictFromDense(booster, values, config, proxy, &out_shape, - &out_dim, &out_result); + result = + XGBoosterPredictFromDense(booster, values, config, proxy, &out_shape, &out_dim, &out_result); if (result == 0) { ret = collect_prediction_results(env, out_shape, out_dim, out_result); } else { @@ -1141,8 +1000,7 @@ ERL_NIF_TERM EXGBoosterPredictFromDense(ErlNifEnv *env, int argc, return ret; } -ERL_NIF_TERM EXGBoosterPredictFromCSR(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { +ERL_NIF_TERM EXGBoosterPredictFromCSR(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { BoosterHandle booster; BoosterHandle **booster_resource = NULL; DMatrixHandle proxy; @@ -1165,24 +1023,26 @@ ERL_NIF_TERM EXGBoosterPredictFromCSR(ErlNifEnv *env, int argc, goto END; } - if (!enif_get_resource(env, argv[0], Booster_RESOURCE_TYPE, - (void *)&(booster_resource))) { + if (!enif_get_resource(env, argv[0], Booster_RESOURCE_TYPE, (void *)&(booster_resource))) { ret = exg_error(env, "Invalid Booster"); goto END; } // Build ArrayInterface JSON for each sparse array from components - if (!exg_build_array_interface_json(env, argv[1], argv[2], argv[3], argv[4], &indptr, &error_msg)) { + if (!exg_build_array_interface_json(env, argv[1], argv[2], argv[3], argv[4], &indptr, + &error_msg)) { ret = exg_error(env, error_msg ? error_msg : "Failed to extract indptr ArrayInterface"); goto END; } - if (!exg_build_array_interface_json(env, argv[5], argv[6], argv[7], argv[8], &indices, &error_msg)) { + if (!exg_build_array_interface_json(env, argv[5], argv[6], argv[7], argv[8], &indices, + &error_msg)) { ret = exg_error(env, error_msg ? error_msg : "Failed to extract indices ArrayInterface"); goto END; } - if (!exg_build_array_interface_json(env, argv[9], argv[10], argv[11], argv[12], &data, &error_msg)) { + if (!exg_build_array_interface_json(env, argv[9], argv[10], argv[11], argv[12], &data, + &error_msg)) { ret = exg_error(env, error_msg ? error_msg : "Failed to extract data ArrayInterface"); goto END; } @@ -1204,17 +1064,14 @@ ERL_NIF_TERM EXGBoosterPredictFromCSR(ErlNifEnv *env, int argc, goto END; } - if (!enif_get_resource(env, argv[15], DMatrix_RESOURCE_TYPE, - (void *)&(proxy_resource))) { + if (!enif_get_resource(env, argv[15], DMatrix_RESOURCE_TYPE, (void *)&(proxy_resource))) { proxy = NULL; } else { proxy = *proxy_resource; } booster = *booster_resource; - result = - XGBoosterPredictFromCSR(booster, indptr, indices, data, - ncols, config, proxy, &out_shape, - &out_dim, &out_result); + result = XGBoosterPredictFromCSR(booster, indptr, indices, data, ncols, config, proxy, &out_shape, + &out_dim, &out_result); if (result == 0) { ret = collect_prediction_results(env, out_shape, out_dim, out_result); } else { @@ -1236,8 +1093,7 @@ ERL_NIF_TERM EXGBoosterPredictFromCSR(ErlNifEnv *env, int argc, return ret; } -ERL_NIF_TERM EXGBoosterLoadModel(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { +ERL_NIF_TERM EXGBoosterLoadModel(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { BoosterHandle booster; char *fname = NULL; int result = -1; @@ -1269,8 +1125,7 @@ ERL_NIF_TERM EXGBoosterLoadModel(ErlNifEnv *env, int argc, return ret; } -ERL_NIF_TERM EXGBoosterSaveModel(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { +ERL_NIF_TERM EXGBoosterSaveModel(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { BoosterHandle booster; BoosterHandle **booster_resource = NULL; char *fname = NULL; @@ -1280,8 +1135,7 @@ ERL_NIF_TERM EXGBoosterSaveModel(ErlNifEnv *env, int argc, ret = exg_error(env, "Wrong number of arguments"); goto END; } - if (!enif_get_resource(env, argv[0], Booster_RESOURCE_TYPE, - (void *)&(booster_resource))) { + if (!enif_get_resource(env, argv[0], Booster_RESOURCE_TYPE, (void *)&(booster_resource))) { ret = exg_error(env, "Invalid Booster"); goto END; } @@ -1303,8 +1157,7 @@ ERL_NIF_TERM EXGBoosterSaveModel(ErlNifEnv *env, int argc, return ret; } -ERL_NIF_TERM EXGBoosterSerializeToBuffer(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { +ERL_NIF_TERM EXGBoosterSerializeToBuffer(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { BoosterHandle booster; BoosterHandle **booster_resource = NULL; bst_ulong out_len = 0; @@ -1315,8 +1168,7 @@ ERL_NIF_TERM EXGBoosterSerializeToBuffer(ErlNifEnv *env, int argc, ret = exg_error(env, "Wrong number of arguments"); goto END; } - if (!enif_get_resource(env, argv[0], Booster_RESOURCE_TYPE, - (void *)&(booster_resource))) { + if (!enif_get_resource(env, argv[0], Booster_RESOURCE_TYPE, (void *)&(booster_resource))) { ret = exg_error(env, "Invalid Booster"); goto END; } @@ -1342,8 +1194,7 @@ ERL_NIF_TERM EXGBoosterSerializeToBuffer(ErlNifEnv *env, int argc, return ret; } -ERL_NIF_TERM EXGBoosterDeserializeFromBuffer(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { +ERL_NIF_TERM EXGBoosterDeserializeFromBuffer(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { BoosterHandle booster; char *buf = NULL; int result = -1; @@ -1378,8 +1229,7 @@ ERL_NIF_TERM EXGBoosterDeserializeFromBuffer(ErlNifEnv *env, int argc, return ret; } -ERL_NIF_TERM EXGBoosterLoadModelFromBuffer(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { +ERL_NIF_TERM EXGBoosterLoadModelFromBuffer(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { BoosterHandle booster; char *buf = NULL; int result = -1; @@ -1414,8 +1264,7 @@ ERL_NIF_TERM EXGBoosterLoadModelFromBuffer(ErlNifEnv *env, int argc, return ret; } -ERL_NIF_TERM EXGBoosterSaveModelToBuffer(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { +ERL_NIF_TERM EXGBoosterSaveModelToBuffer(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { BoosterHandle booster; BoosterHandle **booster_resource = NULL; bst_ulong out_len = 0; @@ -1427,14 +1276,12 @@ ERL_NIF_TERM EXGBoosterSaveModelToBuffer(ErlNifEnv *env, int argc, ret = exg_error(env, "Wrong number of arguments"); goto END; } - if (!enif_get_resource(env, argv[0], Booster_RESOURCE_TYPE, - (void *)&(booster_resource))) { + if (!enif_get_resource(env, argv[0], Booster_RESOURCE_TYPE, (void *)&(booster_resource))) { ret = exg_error(env, "Invalid Booster"); goto END; } if (!exg_get_string(env, argv[1], &config)) { - ret = exg_error(env, - "Invalid config -- config should be a JSON-encoded string"); + ret = exg_error(env, "Invalid config -- config should be a JSON-encoded string"); goto END; } booster = *booster_resource; @@ -1462,8 +1309,7 @@ ERL_NIF_TERM EXGBoosterSaveModelToBuffer(ErlNifEnv *env, int argc, return ret; } -ERL_NIF_TERM EXGBoosterSaveJsonConfig(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { +ERL_NIF_TERM EXGBoosterSaveJsonConfig(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { BoosterHandle booster; BoosterHandle **booster_resource = NULL; bst_ulong out_len = 0; @@ -1474,8 +1320,7 @@ ERL_NIF_TERM EXGBoosterSaveJsonConfig(ErlNifEnv *env, int argc, ret = exg_error(env, "Wrong number of arguments"); goto END; } - if (!enif_get_resource(env, argv[0], Booster_RESOURCE_TYPE, - (void *)&(booster_resource))) { + if (!enif_get_resource(env, argv[0], Booster_RESOURCE_TYPE, (void *)&(booster_resource))) { ret = exg_error(env, "Invalid Booster"); goto END; } @@ -1501,8 +1346,7 @@ ERL_NIF_TERM EXGBoosterSaveJsonConfig(ErlNifEnv *env, int argc, return ret; } -ERL_NIF_TERM EXGBoosterLoadJsonConfig(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { +ERL_NIF_TERM EXGBoosterLoadJsonConfig(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { BoosterHandle booster; BoosterHandle **booster_resource = NULL; char *buf = NULL; @@ -1513,8 +1357,7 @@ ERL_NIF_TERM EXGBoosterLoadJsonConfig(ErlNifEnv *env, int argc, ret = exg_error(env, "Wrong number of arguments"); goto END; } - if (!enif_get_resource(env, argv[0], Booster_RESOURCE_TYPE, - (void *)&(booster_resource))) { + if (!enif_get_resource(env, argv[0], Booster_RESOURCE_TYPE, (void *)&(booster_resource))) { ret = exg_error(env, "Invalid Booster"); goto END; } @@ -1538,8 +1381,7 @@ ERL_NIF_TERM EXGBoosterLoadJsonConfig(ErlNifEnv *env, int argc, return ret; } -ERL_NIF_TERM EXGBoosterDumpModelEx(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { +ERL_NIF_TERM EXGBoosterDumpModelEx(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { BoosterHandle booster; BoosterHandle **booster_resource = NULL; bst_ulong out_len = 0; @@ -1553,8 +1395,7 @@ ERL_NIF_TERM EXGBoosterDumpModelEx(ErlNifEnv *env, int argc, ret = exg_error(env, "Wrong number of arguments"); goto END; } - if (!enif_get_resource(env, argv[0], Booster_RESOURCE_TYPE, - (void *)&(booster_resource))) { + if (!enif_get_resource(env, argv[0], Booster_RESOURCE_TYPE, (void *)&(booster_resource))) { ret = exg_error(env, "Invalid Booster"); goto END; } @@ -1571,8 +1412,7 @@ ERL_NIF_TERM EXGBoosterDumpModelEx(ErlNifEnv *env, int argc, goto END; } booster = *booster_resource; - result = XGBoosterDumpModelEx(booster, fmap, with_stats, format, &out_len, - &out_dump_array); + result = XGBoosterDumpModelEx(booster, fmap, with_stats, format, &out_len, &out_dump_array); if (result == 0) { ERL_NIF_TERM arr[out_len]; for (bst_ulong i = 0; i < out_len; ++i) { diff --git a/c/exgboost/src/config.c b/c/exgboost/src/config.c index 9590d66..0cc13cb 100644 --- a/c/exgboost/src/config.c +++ b/c/exgboost/src/config.c @@ -1,11 +1,9 @@ #include "booster.h" -ERL_NIF_TERM EXGBoostVersion(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { +ERL_NIF_TERM EXGBoostVersion(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { int major, minor, patch; XGBoostVersion(&major, &minor, &patch); - return exg_ok(env, enif_make_tuple3(env, enif_make_int(env, major), - enif_make_int(env, minor), + return exg_ok(env, enif_make_tuple3(env, enif_make_int(env, major), enif_make_int(env, minor), enif_make_int(env, patch))); } @@ -30,8 +28,7 @@ ERL_NIF_TERM EXGBuildInfo(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { return ret; } -ERL_NIF_TERM EXGBSetGlobalConfig(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { +ERL_NIF_TERM EXGBSetGlobalConfig(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { char *config = NULL; int result = -1; ERL_NIF_TERM ret = 0; @@ -57,8 +54,7 @@ ERL_NIF_TERM EXGBSetGlobalConfig(ErlNifEnv *env, int argc, return ret; } -ERL_NIF_TERM EXGBGetGlobalConfig(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { +ERL_NIF_TERM EXGBGetGlobalConfig(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { const char *out = NULL; int result = -1; ERL_NIF_TERM ret = 0; diff --git a/c/exgboost/src/dmatrix.c b/c/exgboost/src/dmatrix.c index d92e1e3..8d5dbb2 100644 --- a/c/exgboost/src/dmatrix.c +++ b/c/exgboost/src/dmatrix.c @@ -1,14 +1,14 @@ #include "dmatrix.h" -#include "yyjson.h" + #include #include #include -static ERL_NIF_TERM make_DMatrix_resource(ErlNifEnv *env, - DMatrixHandle handle) { +#include "yyjson.h" + +static ERL_NIF_TERM make_DMatrix_resource(ErlNifEnv *env, DMatrixHandle handle) { ERL_NIF_TERM ret = -1; - DMatrixHandle **resource = - enif_alloc_resource(DMatrix_RESOURCE_TYPE, sizeof(DMatrixHandle *)); + DMatrixHandle **resource = enif_alloc_resource(DMatrix_RESOURCE_TYPE, sizeof(DMatrixHandle *)); if (resource != NULL) { *resource = handle; // BEAM resource now owns the handle and releases it in resource cleanup. @@ -21,8 +21,7 @@ static ERL_NIF_TERM make_DMatrix_resource(ErlNifEnv *env, } // Deprecated since XGBoost 2.0.0 -ERL_NIF_TERM EXGDMatrixCreateFromFile(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { +ERL_NIF_TERM EXGDMatrixCreateFromFile(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { char *fname = NULL; char *format = NULL; int silent = 0; @@ -59,8 +58,7 @@ ERL_NIF_TERM EXGDMatrixCreateFromFile(ErlNifEnv *env, int argc, return ret; } -ERL_NIF_TERM EXGDMatrixCreateFromURI(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { +ERL_NIF_TERM EXGDMatrixCreateFromURI(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { char *config = NULL; DMatrixHandle handle; int result = -1; @@ -87,8 +85,7 @@ ERL_NIF_TERM EXGDMatrixCreateFromURI(ErlNifEnv *env, int argc, return ret; } -ERL_NIF_TERM EXGDMatrixCreateFromMat(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { +ERL_NIF_TERM EXGDMatrixCreateFromMat(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { ErlNifBinary bin; int result = -1; float *mat = NULL; @@ -126,8 +123,7 @@ ERL_NIF_TERM EXGDMatrixCreateFromMat(ErlNifEnv *env, int argc, } // The DMatrix wlil keep ahold of this data, so we don't need to free it // Will be freed when DMatrix is freed in resource destructor - result = XGDMatrixCreateFromMat(mat, (bst_ulong)nrow, (bst_ulong)ncol, - missing, &handle); + result = XGDMatrixCreateFromMat(mat, (bst_ulong)nrow, (bst_ulong)ncol, missing, &handle); if (result == 0) { ret = make_DMatrix_resource(env, handle); } else { @@ -137,8 +133,7 @@ ERL_NIF_TERM EXGDMatrixCreateFromMat(ErlNifEnv *env, int argc, return ret; } -ERL_NIF_TERM EXGDMatrixCreateFromSparse(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { +ERL_NIF_TERM EXGDMatrixCreateFromSparse(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { int result = -1; char *indptr_interface = NULL; char *indices_interface = NULL; @@ -159,39 +154,39 @@ ERL_NIF_TERM EXGDMatrixCreateFromSparse(ErlNifEnv *env, int argc, } // Extract ArrayInterface tuples: {binary, typestr, shape, readonly} - if (!exg_get_array_interface_tuple(env, argv[0], &indptr_binary, &indptr_typestr, - &indptr_shape, &indptr_readonly, &error_msg)) { + if (!exg_get_array_interface_tuple(env, argv[0], &indptr_binary, &indptr_typestr, &indptr_shape, + &indptr_readonly, &error_msg)) { ret = exg_error(env, error_msg ? error_msg : "Failed to extract indptr ArrayInterface tuple"); goto END; } if (!exg_get_array_interface_tuple(env, argv[1], &indices_binary, &indices_typestr, - &indices_shape, &indices_readonly, &error_msg)) { + &indices_shape, &indices_readonly, &error_msg)) { ret = exg_error(env, error_msg ? error_msg : "Failed to extract indices ArrayInterface tuple"); goto END; } - if (!exg_get_array_interface_tuple(env, argv[2], &data_binary, &data_typestr, - &data_shape, &data_readonly, &error_msg)) { + if (!exg_get_array_interface_tuple(env, argv[2], &data_binary, &data_typestr, &data_shape, + &data_readonly, &error_msg)) { ret = exg_error(env, error_msg ? error_msg : "Failed to extract data ArrayInterface tuple"); goto END; } // Build JSON from extracted components if (!exg_build_array_interface_json(env, indptr_binary, indptr_typestr, indptr_shape, - indptr_readonly, &indptr_interface, &error_msg)) { + indptr_readonly, &indptr_interface, &error_msg)) { ret = exg_error(env, error_msg ? error_msg : "Failed to build indptr ArrayInterface"); goto END; } if (!exg_build_array_interface_json(env, indices_binary, indices_typestr, indices_shape, - indices_readonly, &indices_interface, &error_msg)) { + indices_readonly, &indices_interface, &error_msg)) { ret = exg_error(env, error_msg ? error_msg : "Failed to build indices ArrayInterface"); goto END; } - if (!exg_build_array_interface_json(env, data_binary, data_typestr, data_shape, - data_readonly, &data_interface, &error_msg)) { + if (!exg_build_array_interface_json(env, data_binary, data_typestr, data_shape, data_readonly, + &data_interface, &error_msg)) { ret = exg_error(env, error_msg ? error_msg : "Failed to build data ArrayInterface"); goto END; } @@ -221,11 +216,11 @@ ERL_NIF_TERM EXGDMatrixCreateFromSparse(ErlNifEnv *env, int argc, goto END; } if (strcmp(format, "csr") == 0) { - result = XGDMatrixCreateFromCSR(indptr_interface, indices_interface, - data_interface, n, config, &handle); + result = XGDMatrixCreateFromCSR(indptr_interface, indices_interface, data_interface, n, config, + &handle); } else if (strcmp(format, "csc") == 0) { - result = XGDMatrixCreateFromCSC(indptr_interface, indices_interface, - data_interface, n, config, &handle); + result = XGDMatrixCreateFromCSC(indptr_interface, indices_interface, data_interface, n, config, + &handle); } else { ret = exg_error(env, "Format must in ['csr','csc']"); goto END; @@ -259,8 +254,7 @@ ERL_NIF_TERM EXGDMatrixCreateFromSparse(ErlNifEnv *env, int argc, return ret; } -ERL_NIF_TERM EXGDMatrixCreateFromDense(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { +ERL_NIF_TERM EXGDMatrixCreateFromDense(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { int result = -1; char *array_interface = NULL; const char *error_msg = NULL; @@ -275,15 +269,15 @@ ERL_NIF_TERM EXGDMatrixCreateFromDense(ErlNifEnv *env, int argc, } // Extract ArrayInterface tuple: {binary, typestr, shape, readonly} - if (!exg_get_array_interface_tuple(env, argv[0], &array_binary, &array_typestr, - &array_shape, &array_readonly, &error_msg)) { + if (!exg_get_array_interface_tuple(env, argv[0], &array_binary, &array_typestr, &array_shape, + &array_readonly, &error_msg)) { ret = exg_error(env, error_msg ? error_msg : "Failed to extract ArrayInterface tuple"); goto END; } // Build ArrayInterface JSON from components - if (!exg_build_array_interface_json(env, array_binary, array_typestr, array_shape, - array_readonly, &array_interface, &error_msg)) { + if (!exg_build_array_interface_json(env, array_binary, array_typestr, array_shape, array_readonly, + &array_interface, &error_msg)) { ret = exg_error(env, error_msg ? error_msg : "Failed to build ArrayInterface"); goto END; } @@ -308,8 +302,7 @@ ERL_NIF_TERM EXGDMatrixCreateFromDense(ErlNifEnv *env, int argc, return ret; } -ERL_NIF_TERM EXGDMatrixSetStrFeatureInfo(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { +ERL_NIF_TERM EXGDMatrixSetStrFeatureInfo(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { DMatrixHandle handle; DMatrixHandle **resource = NULL; char **features = NULL; @@ -321,8 +314,7 @@ ERL_NIF_TERM EXGDMatrixSetStrFeatureInfo(ErlNifEnv *env, int argc, ret = exg_error(env, "Wrong number of arguments"); goto END; } - if (!enif_get_resource(env, argv[0], DMatrix_RESOURCE_TYPE, - (void *)&resource)) { + if (!enif_get_resource(env, argv[0], DMatrix_RESOURCE_TYPE, (void *)&resource)) { ret = exg_error(env, "DMatrix must be a resource"); goto END; } @@ -334,15 +326,13 @@ ERL_NIF_TERM EXGDMatrixSetStrFeatureInfo(ErlNifEnv *env, int argc, ret = exg_error(env, "Features must be a list"); goto END; } - if (strcmp(field, "feature_type") != 0 && - strcmp(field, "feature_name") != 0) { + if (strcmp(field, "feature_type") != 0 && strcmp(field, "feature_name") != 0) { ret = exg_error(env, "Field must be in ['feature_type', 'feature_name']"); goto END; } handle = *resource; // XGBoost reads features during the call; caller keeps ownership. - result = XGDMatrixSetStrFeatureInfo(handle, field, - (const char **)features, num_features); + result = XGDMatrixSetStrFeatureInfo(handle, field, (const char **)features, num_features); if (result == 0) { ret = ok_atom(env); } else { @@ -359,8 +349,7 @@ ERL_NIF_TERM EXGDMatrixSetStrFeatureInfo(ErlNifEnv *env, int argc, return ret; } -ERL_NIF_TERM EXGDMatrixGetStrFeatureInfo(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { +ERL_NIF_TERM EXGDMatrixGetStrFeatureInfo(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { DMatrixHandle handle; DMatrixHandle **resource = NULL; char const **c_out_features = NULL; @@ -375,8 +364,7 @@ ERL_NIF_TERM EXGDMatrixGetStrFeatureInfo(ErlNifEnv *env, int argc, goto END; } - if (!enif_get_resource(env, argv[0], DMatrix_RESOURCE_TYPE, - (void *)&resource)) { + if (!enif_get_resource(env, argv[0], DMatrix_RESOURCE_TYPE, (void *)&resource)) { ret = exg_error(env, "DMatrix must be a resource"); goto END; } @@ -386,8 +374,7 @@ ERL_NIF_TERM EXGDMatrixGetStrFeatureInfo(ErlNifEnv *env, int argc, goto END; } - if (strcmp(field, "feature_type") != 0 && - strcmp(field, "feature_name") != 0) { + if (strcmp(field, "feature_type") != 0 && strcmp(field, "feature_name") != 0) { ret = exg_error(env, "Field must be in ['feature_type', 'feature_name']"); goto END; } @@ -396,8 +383,7 @@ ERL_NIF_TERM EXGDMatrixGetStrFeatureInfo(ErlNifEnv *env, int argc, result = XGDMatrixGetStrFeatureInfo(handle, field, &out_size, &c_out_features); if (result == 0) { - if (out_size > UINT_MAX || - out_size > SIZE_MAX / sizeof(*arr)) { + if (out_size > UINT_MAX || out_size > SIZE_MAX / sizeof(*arr)) { ret = exg_error(env, "Result is too large"); goto END; } @@ -416,23 +402,12 @@ ERL_NIF_TERM EXGDMatrixGetStrFeatureInfo(ErlNifEnv *env, int argc, goto END; } - arr[i] = - enif_make_string( - env, - c_out_features[i], - ERL_NIF_LATIN1 - ); + arr[i] = enif_make_string(env, c_out_features[i], ERL_NIF_LATIN1); } } - ERL_NIF_TERM list = - out_size == 0 - ? enif_make_list(env, 0) - : enif_make_list_from_array( - env, - arr, - (unsigned)out_size - ); + ERL_NIF_TERM list = out_size == 0 ? enif_make_list(env, 0) + : enif_make_list_from_array(env, arr, (unsigned)out_size); ret = exg_ok(env, list); } else { @@ -451,8 +426,7 @@ ERL_NIF_TERM EXGDMatrixGetStrFeatureInfo(ErlNifEnv *env, int argc, return ret; } -ERL_NIF_TERM EXGDMatrixNumRow(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { +ERL_NIF_TERM EXGDMatrixNumRow(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { DMatrixHandle handle; DMatrixHandle **resource = NULL; bst_ulong out = 0; @@ -462,8 +436,7 @@ ERL_NIF_TERM EXGDMatrixNumRow(ErlNifEnv *env, int argc, ret = exg_error(env, "Wrong number of arguments"); goto END; } - if (!enif_get_resource(env, argv[0], DMatrix_RESOURCE_TYPE, - (void *)&resource)) { + if (!enif_get_resource(env, argv[0], DMatrix_RESOURCE_TYPE, (void *)&resource)) { ret = exg_error(env, "DMatrix must be a resource"); goto END; } @@ -478,8 +451,7 @@ ERL_NIF_TERM EXGDMatrixNumRow(ErlNifEnv *env, int argc, return ret; } -ERL_NIF_TERM EXGDMatrixNumCol(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { +ERL_NIF_TERM EXGDMatrixNumCol(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { DMatrixHandle handle; DMatrixHandle **resource = NULL; bst_ulong out = 0; @@ -489,8 +461,7 @@ ERL_NIF_TERM EXGDMatrixNumCol(ErlNifEnv *env, int argc, ret = exg_error(env, "Wrong number of arguments"); goto END; } - if (!enif_get_resource(env, argv[0], DMatrix_RESOURCE_TYPE, - (void *)&resource)) { + if (!enif_get_resource(env, argv[0], DMatrix_RESOURCE_TYPE, (void *)&resource)) { ret = exg_error(env, "DMatrix must be a resource"); goto END; } @@ -505,8 +476,7 @@ ERL_NIF_TERM EXGDMatrixNumCol(ErlNifEnv *env, int argc, return ret; } -ERL_NIF_TERM EXGDMatrixNumNonMissing(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { +ERL_NIF_TERM EXGDMatrixNumNonMissing(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { DMatrixHandle handle; DMatrixHandle **resource = NULL; bst_ulong out = 0; @@ -516,8 +486,7 @@ ERL_NIF_TERM EXGDMatrixNumNonMissing(ErlNifEnv *env, int argc, ret = exg_error(env, "Wrong number of arguments"); goto END; } - if (!enif_get_resource(env, argv[0], DMatrix_RESOURCE_TYPE, - (void *)&resource)) { + if (!enif_get_resource(env, argv[0], DMatrix_RESOURCE_TYPE, (void *)&resource)) { ret = exg_error(env, "DMatrix must be a resource"); goto END; } @@ -532,8 +501,7 @@ ERL_NIF_TERM EXGDMatrixNumNonMissing(ErlNifEnv *env, int argc, return ret; } -ERL_NIF_TERM EXGDMatrixSetInfoFromInterface(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { +ERL_NIF_TERM EXGDMatrixSetInfoFromInterface(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { DMatrixHandle handle; DMatrixHandle **resource = NULL; char *field = NULL; @@ -548,8 +516,7 @@ ERL_NIF_TERM EXGDMatrixSetInfoFromInterface(ErlNifEnv *env, int argc, goto END; } - if (!enif_get_resource(env, argv[0], DMatrix_RESOURCE_TYPE, - (void *)&resource)) { + if (!enif_get_resource(env, argv[0], DMatrix_RESOURCE_TYPE, (void *)&resource)) { ret = exg_error(env, "DMatrix must be a resource"); goto END; } @@ -560,27 +527,27 @@ ERL_NIF_TERM EXGDMatrixSetInfoFromInterface(ErlNifEnv *env, int argc, } // Extract ArrayInterface tuple: {binary, typestr, shape, readonly} - if (!exg_get_array_interface_tuple(env, argv[2], &data_binary, &data_typestr, - &data_shape, &data_readonly, &error_msg)) { + if (!exg_get_array_interface_tuple(env, argv[2], &data_binary, &data_typestr, &data_shape, + &data_readonly, &error_msg)) { ret = exg_error(env, error_msg ? error_msg : "Failed to extract ArrayInterface tuple"); goto END; } // Build ArrayInterface JSON from components - if (!exg_build_array_interface_json(env, data_binary, data_typestr, data_shape, - data_readonly, &data_interface, &error_msg)) { + if (!exg_build_array_interface_json(env, data_binary, data_typestr, data_shape, data_readonly, + &data_interface, &error_msg)) { ret = exg_error(env, error_msg ? error_msg : "Failed to build data ArrayInterface"); goto END; } if (strcmp(field, "label") != 0 && strcmp(field, "weight") != 0 && strcmp(field, "base_margin") != 0 && strcmp(field, "group") != 0 && - strcmp(field, "label_lower_bound") != 0 && - strcmp(field, "label_upper_bound") != 0 && + strcmp(field, "label_lower_bound") != 0 && strcmp(field, "label_upper_bound") != 0 && strcmp(field, "feature_weights") != 0) { - ret = exg_error(env, "Field must be in ['label', 'weight', " - "'base_margin','group','label_lower_bound','label_" - "upper_bound','feature_weights']"); + ret = exg_error(env, + "Field must be in ['label', 'weight', " + "'base_margin','group','label_lower_bound','label_" + "upper_bound','feature_weights']"); goto END; } handle = *resource; @@ -600,8 +567,7 @@ ERL_NIF_TERM EXGDMatrixSetInfoFromInterface(ErlNifEnv *env, int argc, return ret; } -ERL_NIF_TERM EXGDMatrixSaveBinary(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { +ERL_NIF_TERM EXGDMatrixSaveBinary(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { DMatrixHandle handle; DMatrixHandle **resource = NULL; char *fname = NULL; @@ -612,8 +578,7 @@ ERL_NIF_TERM EXGDMatrixSaveBinary(ErlNifEnv *env, int argc, ret = exg_error(env, "Wrong number of arguments"); goto END; } - if (!enif_get_resource(env, argv[0], DMatrix_RESOURCE_TYPE, - (void *)&resource)) { + if (!enif_get_resource(env, argv[0], DMatrix_RESOURCE_TYPE, (void *)&resource)) { ret = exg_error(env, "DMatrix must be a resource"); goto END; } @@ -639,8 +604,7 @@ ERL_NIF_TERM EXGDMatrixSaveBinary(ErlNifEnv *env, int argc, return ret; } -ERL_NIF_TERM EXGDMatrixGetFloatInfo(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { +ERL_NIF_TERM EXGDMatrixGetFloatInfo(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { DMatrixHandle handle; DMatrixHandle **resource = NULL; char *field = NULL; @@ -654,8 +618,7 @@ ERL_NIF_TERM EXGDMatrixGetFloatInfo(ErlNifEnv *env, int argc, ret = exg_error(env, "Wrong number of arguments"); goto END; } - if (!enif_get_resource(env, argv[0], DMatrix_RESOURCE_TYPE, - (void *)&resource)) { + if (!enif_get_resource(env, argv[0], DMatrix_RESOURCE_TYPE, (void *)&resource)) { ret = exg_error(env, "DMatrix must be a resource"); goto END; } @@ -665,11 +628,11 @@ ERL_NIF_TERM EXGDMatrixGetFloatInfo(ErlNifEnv *env, int argc, } if (strcmp(field, "label") != 0 && strcmp(field, "weight") != 0 && strcmp(field, "base_margin") != 0 && strcmp(field, "label_lower_bound") && - strcmp(field, "label_upper_bound") && - strcmp(field, "feature_weights") != 0) { - ret = exg_error(env, "Field must be in ['label', 'weight', " - "'base_margin','label_lower_bound','label_" - "upper_bound','feature_weights']"); + strcmp(field, "label_upper_bound") && strcmp(field, "feature_weights") != 0) { + ret = exg_error(env, + "Field must be in ['label', 'weight', " + "'base_margin','label_lower_bound','label_" + "upper_bound','feature_weights']"); goto END; } handle = *resource; @@ -694,8 +657,7 @@ ERL_NIF_TERM EXGDMatrixGetFloatInfo(ErlNifEnv *env, int argc, return ret; } -ERL_NIF_TERM EXGDMatrixGetUIntInfo(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { +ERL_NIF_TERM EXGDMatrixGetUIntInfo(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { DMatrixHandle handle; DMatrixHandle **resource = NULL; char *field = NULL; @@ -709,8 +671,7 @@ ERL_NIF_TERM EXGDMatrixGetUIntInfo(ErlNifEnv *env, int argc, ret = exg_error(env, "Wrong number of arguments"); goto END; } - if (!enif_get_resource(env, argv[0], DMatrix_RESOURCE_TYPE, - (void *)&resource)) { + if (!enif_get_resource(env, argv[0], DMatrix_RESOURCE_TYPE, (void *)&resource)) { ret = exg_error(env, "DMatrix must be a resource"); goto END; } @@ -744,8 +705,7 @@ ERL_NIF_TERM EXGDMatrixGetUIntInfo(ErlNifEnv *env, int argc, return ret; } -ERL_NIF_TERM EXGDMatrixGetDataAsCSR(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { +ERL_NIF_TERM EXGDMatrixGetDataAsCSR(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { DMatrixHandle handle; DMatrixHandle **resource = NULL; bst_ulong num_non_missing = 0; @@ -763,8 +723,7 @@ ERL_NIF_TERM EXGDMatrixGetDataAsCSR(ErlNifEnv *env, int argc, ret = exg_error(env, "Wrong number of arguments"); goto END; } - if (!enif_get_resource(env, argv[0], DMatrix_RESOURCE_TYPE, - (void *)&resource)) { + if (!enif_get_resource(env, argv[0], DMatrix_RESOURCE_TYPE, (void *)&resource)) { ret = exg_error(env, "DMatrix must be a resource"); goto END; } @@ -785,8 +744,7 @@ ERL_NIF_TERM EXGDMatrixGetDataAsCSR(ErlNifEnv *env, int argc, } // Check allocation sizes fit in size_t if (num_rows > SIZE_MAX / sizeof(bst_ulong) - 1 || - num_non_missing > SIZE_MAX / sizeof(unsigned) || - num_non_missing > SIZE_MAX / sizeof(float)) { + num_non_missing > SIZE_MAX / sizeof(unsigned) || num_non_missing > SIZE_MAX / sizeof(float)) { ret = exg_error(env, "Matrix is too large"); goto END; } @@ -797,8 +755,7 @@ ERL_NIF_TERM EXGDMatrixGetDataAsCSR(ErlNifEnv *env, int argc, ret = exg_error(env, "Failed to allocate memory"); goto END; } - result = - XGDMatrixGetDataAsCSR(handle, config, out_indptr, out_indices, out_data); + result = XGDMatrixGetDataAsCSR(handle, config, out_indptr, out_indices, out_data); if (result != 0) { ret = exg_error(env, XGBGetLastError()); goto END; @@ -823,11 +780,10 @@ ERL_NIF_TERM EXGDMatrixGetDataAsCSR(ErlNifEnv *env, int argc, indices[i] = enif_make_uint(env, out_indices[i]); data[i] = enif_make_double(env, out_data[i]); } - ret = - exg_ok(env, enif_make_tuple3( - env, enif_make_list_from_array(env, indptr, (size_t)(num_rows + 1)), - enif_make_list_from_array(env, indices, (size_t)num_non_missing), - enif_make_list_from_array(env, data, (size_t)num_non_missing))); + ret = exg_ok(env, + enif_make_tuple3(env, enif_make_list_from_array(env, indptr, (size_t)(num_rows + 1)), + enif_make_list_from_array(env, indices, (size_t)num_non_missing), + enif_make_list_from_array(env, data, (size_t)num_non_missing))); END: // Mixed allocators: enif_free for enif_alloc buffers, free for malloc buffers. if (config != NULL) { @@ -858,8 +814,7 @@ ERL_NIF_TERM EXGDMatrixGetDataAsCSR(ErlNifEnv *env, int argc, return ret; }; -ERL_NIF_TERM EXGDMatrixSliceDMatrix(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { +ERL_NIF_TERM EXGDMatrixSliceDMatrix(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { DMatrixHandle handle; DMatrixHandle **resource = NULL; ErlNifBinary bin; @@ -871,8 +826,7 @@ ERL_NIF_TERM EXGDMatrixSliceDMatrix(ErlNifEnv *env, int argc, ret = exg_error(env, "Wrong number of arguments"); goto END; } - if (!enif_get_resource(env, argv[0], DMatrix_RESOURCE_TYPE, - (void *)&resource)) { + if (!enif_get_resource(env, argv[0], DMatrix_RESOURCE_TYPE, (void *)&resource)) { ret = exg_error(env, "DMatrix must be a resource"); goto END; } @@ -904,8 +858,7 @@ ERL_NIF_TERM EXGDMatrixSliceDMatrix(ErlNifEnv *env, int argc, goto END; } } - result = XGDMatrixSliceDMatrixEx(handle, (int *)bin.data, index_count, &out, - allow_groups); + result = XGDMatrixSliceDMatrixEx(handle, (int *)bin.data, index_count, &out, allow_groups); if (0 == result) { ret = make_DMatrix_resource(env, out); } else { @@ -915,8 +868,7 @@ ERL_NIF_TERM EXGDMatrixSliceDMatrix(ErlNifEnv *env, int argc, return ret; } -ERL_NIF_TERM EXGProxyDMatrixCreate(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { +ERL_NIF_TERM EXGProxyDMatrixCreate(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { DMatrixHandle handle; int result = -1; ERL_NIF_TERM ret = -1; @@ -935,11 +887,8 @@ ERL_NIF_TERM EXGProxyDMatrixCreate(ErlNifEnv *env, int argc, } // Helper to parse ArrayInterface JSON and copy data atomically -static int exg_parse_and_copy_array_interface( - ErlNifEnv *env, - const char *json_str, - ERL_NIF_TERM *out_map -) { +static int exg_parse_and_copy_array_interface(ErlNifEnv *env, const char *json_str, + ERL_NIF_TERM *out_map) { int ok = 0; yyjson_doc *doc = NULL; @@ -958,11 +907,8 @@ static int exg_parse_and_copy_array_interface( yyjson_val *data_arr = yyjson_obj_get(root, "data"); yyjson_val *shape_arr = yyjson_obj_get(root, "shape"); - if (!yyjson_is_uint(version_val) || - yyjson_get_uint(version_val) != 3 || - !yyjson_is_str(typestr_val) || - !yyjson_is_arr(data_arr) || - !yyjson_is_arr(shape_arr)) { + if (!yyjson_is_uint(version_val) || yyjson_get_uint(version_val) != 3 || + !yyjson_is_str(typestr_val) || !yyjson_is_arr(data_arr) || !yyjson_is_arr(shape_arr)) { goto CLEANUP; } @@ -973,8 +919,7 @@ static int exg_parse_and_copy_array_interface( yyjson_val *address_val = yyjson_arr_get(data_arr, 0); yyjson_val *readonly_val = yyjson_arr_get(data_arr, 1); - if (!yyjson_is_uint(address_val) || - !yyjson_is_bool(readonly_val)) { + if (!yyjson_is_uint(address_val) || !yyjson_is_bool(readonly_val)) { goto CLEANUP; } @@ -990,10 +935,7 @@ static int exg_parse_and_copy_array_interface( size_t bytes_per_elem = 0; const char *parse_error = NULL; - if (!exg_parse_typestr( - typestr, - &bytes_per_elem, - &parse_error)) { + if (!exg_parse_typestr(typestr, &bytes_per_elem, &parse_error)) { goto CLEANUP; } @@ -1032,8 +974,7 @@ static int exg_parse_and_copy_array_interface( } ERL_NIF_TERM binary_term; - unsigned char *destination = - enif_make_new_binary(env, total_size, &binary_term); + unsigned char *destination = enif_make_new_binary(env, total_size, &binary_term); if (destination == NULL && total_size != 0) { goto CLEANUP; @@ -1045,8 +986,7 @@ static int exg_parse_and_copy_array_interface( size_t typestr_len = strlen(typestr); ERL_NIF_TERM typestr_term; - unsigned char *typestr_destination = - enif_make_new_binary(env, typestr_len, &typestr_term); + unsigned char *typestr_destination = enif_make_new_binary(env, typestr_len, &typestr_term); if (typestr_destination == NULL && typestr_len != 0) { goto CLEANUP; @@ -1056,10 +996,7 @@ static int exg_parse_and_copy_array_interface( memcpy(typestr_destination, typestr, typestr_len); } - ERL_NIF_TERM shape_term = - enif_make_list1( - env, - enif_make_uint64(env, (ErlNifUInt64)dim)); + ERL_NIF_TERM shape_term = enif_make_list1(env, enif_make_uint64(env, (ErlNifUInt64)dim)); ok = exg_make_array_interface_map(env, binary_term, typestr_term, shape_term, out_map); @@ -1071,8 +1008,7 @@ static int exg_parse_and_copy_array_interface( return ok; } -ERL_NIF_TERM EXGDMatrixGetQuantileCut(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { +ERL_NIF_TERM EXGDMatrixGetQuantileCut(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { DMatrixHandle handle; DMatrixHandle **resource = NULL; char *config = NULL; diff --git a/c/exgboost/src/exgboost.c b/c/exgboost/src/exgboost.c index cdb1416..94f07a4 100644 --- a/c/exgboost/src/exgboost.c +++ b/c/exgboost/src/exgboost.c @@ -3,28 +3,25 @@ static int load(ErlNifEnv *env, void **priv_data, ERL_NIF_TERM load_info) { exg_init_atoms(env); - DMatrix_RESOURCE_TYPE = enif_open_resource_type( - env, NULL, "DMatrix_RESOURCE_TYPE", DMatrix_RESOURCE_TYPE_cleanup, - (ErlNifResourceFlags)(ERL_NIF_RT_CREATE | ERL_NIF_RT_TAKEOVER), NULL); - Booster_RESOURCE_TYPE = enif_open_resource_type( - env, NULL, "Booster_RESOURCE_TYPE", Booster_RESOURCE_TYPE_cleanup, - (ErlNifResourceFlags)(ERL_NIF_RT_CREATE | ERL_NIF_RT_TAKEOVER), NULL); + DMatrix_RESOURCE_TYPE = + enif_open_resource_type(env, NULL, "DMatrix_RESOURCE_TYPE", DMatrix_RESOURCE_TYPE_cleanup, + (ErlNifResourceFlags)(ERL_NIF_RT_CREATE | ERL_NIF_RT_TAKEOVER), NULL); + Booster_RESOURCE_TYPE = + enif_open_resource_type(env, NULL, "Booster_RESOURCE_TYPE", Booster_RESOURCE_TYPE_cleanup, + (ErlNifResourceFlags)(ERL_NIF_RT_CREATE | ERL_NIF_RT_TAKEOVER), NULL); if (DMatrix_RESOURCE_TYPE == NULL || Booster_RESOURCE_TYPE == NULL) { return 1; } return 0; } -static int upgrade(ErlNifEnv *env, void **priv_data, void **old_priv_data, - ERL_NIF_TERM load_info) { +static int upgrade(ErlNifEnv *env, void **priv_data, void **old_priv_data, ERL_NIF_TERM load_info) { exg_init_atoms(env); DMatrix_RESOURCE_TYPE = enif_open_resource_type( - env, NULL, "DMatrix_RESOURCE_TYPE", DMatrix_RESOURCE_TYPE_cleanup, - ERL_NIF_RT_TAKEOVER, NULL); + env, NULL, "DMatrix_RESOURCE_TYPE", DMatrix_RESOURCE_TYPE_cleanup, ERL_NIF_RT_TAKEOVER, NULL); Booster_RESOURCE_TYPE = enif_open_resource_type( - env, NULL, "Booster_RESOURCE_TYPE", Booster_RESOURCE_TYPE_cleanup, - ERL_NIF_RT_TAKEOVER, NULL); + env, NULL, "Booster_RESOURCE_TYPE", Booster_RESOURCE_TYPE_cleanup, ERL_NIF_RT_TAKEOVER, NULL); if (DMatrix_RESOURCE_TYPE == NULL || Booster_RESOURCE_TYPE == NULL) { return 1; } @@ -38,10 +35,8 @@ static ErlNifFunc nif_funcs[] = { {"set_global_config", 1, EXGBSetGlobalConfig}, {"get_global_config", 0, EXGBGetGlobalConfig}, {"proxy_dmatrix_create", 0, EXGProxyDMatrixCreate}, - {"dmatrix_create_from_file", 2, EXGDMatrixCreateFromFile, - ERL_NIF_DIRTY_JOB_IO_BOUND}, - {"dmatrix_create_from_uri", 1, EXGDMatrixCreateFromURI, - ERL_NIF_DIRTY_JOB_IO_BOUND}, + {"dmatrix_create_from_file", 2, EXGDMatrixCreateFromFile, ERL_NIF_DIRTY_JOB_IO_BOUND}, + {"dmatrix_create_from_uri", 1, EXGDMatrixCreateFromURI, ERL_NIF_DIRTY_JOB_IO_BOUND}, {"dmatrix_create_from_mat", 4, EXGDMatrixCreateFromMat}, {"dmatrix_create_from_sparse", 6, EXGDMatrixCreateFromSparse}, {"dmatrix_create_from_dense", 2, EXGDMatrixCreateFromDense}, @@ -61,12 +56,9 @@ static ErlNifFunc nif_funcs[] = { {"booster_boosted_rounds", 1, EXGBoosterBoostedRounds}, {"booster_set_param", 3, EXGBoosterSetParam}, {"booster_get_num_feature", 1, EXGBoosterGetNumFeature}, - {"booster_update_one_iter", 3, EXGBoosterUpdateOneIter, - ERL_NIF_DIRTY_JOB_CPU_BOUND}, - {"booster_boost_one_iter", 4, EXGBoosterBoostOneIter, - ERL_NIF_DIRTY_JOB_CPU_BOUND}, - {"booster_eval_one_iter", 4, EXGBoosterEvalOneIter, - ERL_NIF_DIRTY_JOB_CPU_BOUND}, + {"booster_update_one_iter", 3, EXGBoosterUpdateOneIter, ERL_NIF_DIRTY_JOB_CPU_BOUND}, + {"booster_boost_one_iter", 4, EXGBoosterBoostOneIter, ERL_NIF_DIRTY_JOB_CPU_BOUND}, + {"booster_eval_one_iter", 4, EXGBoosterEvalOneIter, ERL_NIF_DIRTY_JOB_CPU_BOUND}, {"booster_get_attr_names", 1, EXGBoosterGetAttrNames}, {"booster_get_attr", 2, EXGBoosterGetAttr}, {"booster_set_attr", 3, EXGBoosterSetAttr}, @@ -74,27 +66,19 @@ static ErlNifFunc nif_funcs[] = { {"booster_get_str_feature_info", 2, EXGBoosterGetStrFeatureInfo}, {"booster_feature_score", 2, EXGBoosterFeatureScore}, {"booster_slice", 4, EXGBoosterSlice}, - {"booster_predict_from_dmatrix", 3, EXGBoosterPredictFromDMatrix, - ERL_NIF_DIRTY_JOB_CPU_BOUND}, - {"booster_predict_from_dense", 7, EXGBoosterPredictFromDense, - ERL_NIF_DIRTY_JOB_CPU_BOUND}, - {"booster_predict_from_csr", 16, EXGBoosterPredictFromCSR, - ERL_NIF_DIRTY_JOB_CPU_BOUND}, + {"booster_predict_from_dmatrix", 3, EXGBoosterPredictFromDMatrix, ERL_NIF_DIRTY_JOB_CPU_BOUND}, + {"booster_predict_from_dense", 7, EXGBoosterPredictFromDense, ERL_NIF_DIRTY_JOB_CPU_BOUND}, + {"booster_predict_from_csr", 16, EXGBoosterPredictFromCSR, ERL_NIF_DIRTY_JOB_CPU_BOUND}, {"booster_load_model", 1, EXGBoosterLoadModel, ERL_NIF_DIRTY_JOB_IO_BOUND}, {"booster_save_model", 2, EXGBoosterSaveModel, ERL_NIF_DIRTY_JOB_IO_BOUND}, // These all return binaries so they're CPU bound rather than IO bound - {"booster_serialize_to_buffer", 1, EXGBoosterSerializeToBuffer, - ERL_NIF_DIRTY_JOB_CPU_BOUND}, + {"booster_serialize_to_buffer", 1, EXGBoosterSerializeToBuffer, ERL_NIF_DIRTY_JOB_CPU_BOUND}, {"booster_deserialize_from_buffer", 1, EXGBoosterDeserializeFromBuffer, ERL_NIF_DIRTY_JOB_CPU_BOUND}, - {"booster_save_model_to_buffer", 2, EXGBoosterSaveModelToBuffer, - ERL_NIF_DIRTY_JOB_CPU_BOUND}, + {"booster_save_model_to_buffer", 2, EXGBoosterSaveModelToBuffer, ERL_NIF_DIRTY_JOB_CPU_BOUND}, {"booster_load_model_from_buffer", 1, EXGBoosterLoadModelFromBuffer, ERL_NIF_DIRTY_JOB_CPU_BOUND}, - {"booster_load_json_config", 2, EXGBoosterLoadJsonConfig, - ERL_NIF_DIRTY_JOB_CPU_BOUND}, - {"booster_dump_model", 4, EXGBoosterDumpModelEx, - ERL_NIF_DIRTY_JOB_CPU_BOUND}, - {"booster_save_json_config", 1, EXGBoosterSaveJsonConfig, - ERL_NIF_DIRTY_JOB_CPU_BOUND}}; + {"booster_load_json_config", 2, EXGBoosterLoadJsonConfig, ERL_NIF_DIRTY_JOB_CPU_BOUND}, + {"booster_dump_model", 4, EXGBoosterDumpModelEx, ERL_NIF_DIRTY_JOB_CPU_BOUND}, + {"booster_save_json_config", 1, EXGBoosterSaveJsonConfig, ERL_NIF_DIRTY_JOB_CPU_BOUND}}; ERL_NIF_INIT(Elixir.EXGBoost.NIF, nif_funcs, load, NULL, upgrade, NULL) diff --git a/c/exgboost/src/utils.c b/c/exgboost/src/utils.c index 7cfe020..5102414 100644 --- a/c/exgboost/src/utils.c +++ b/c/exgboost/src/utils.c @@ -1,13 +1,12 @@ #include "utils.h" + #include #include #include #include // Ensure bst_ulong and ErlNifUInt64 are both 64-bit for safe conversions -_Static_assert( - sizeof(bst_ulong) == sizeof(ErlNifUInt64), - "bst_ulong and ErlNifUInt64 must both be 64-bit" -); +_Static_assert(sizeof(bst_ulong) == sizeof(ErlNifUInt64), + "bst_ulong and ErlNifUInt64 must both be 64-bit"); // Cached atoms static ERL_NIF_TERM ATOM_TRUE; @@ -104,8 +103,7 @@ int exg_get_list(ErlNifEnv *env, ERL_NIF_TERM term, double **out) { return 1; } -int exg_get_string_list(ErlNifEnv *env, ERL_NIF_TERM term, char ***out, - unsigned *len) { +int exg_get_string_list(ErlNifEnv *env, ERL_NIF_TERM term, char ***out, unsigned *len) { ERL_NIF_TERM head, tail; int i = 0; if (!enif_get_list_length(env, term, len)) { @@ -128,8 +126,7 @@ int exg_get_string_list(ErlNifEnv *env, ERL_NIF_TERM term, char ***out, return 1; } -int exg_get_dmatrix_list(ErlNifEnv *env, ERL_NIF_TERM term, - DMatrixHandle **dmats, unsigned *len) { +int exg_get_dmatrix_list(ErlNifEnv *env, ERL_NIF_TERM term, DMatrixHandle **dmats, unsigned *len) { ERL_NIF_TERM head, tail; int i = 0; if (!enif_get_list_length(env, term, len)) { @@ -141,8 +138,7 @@ int exg_get_dmatrix_list(ErlNifEnv *env, ERL_NIF_TERM term, } while (enif_get_list_cell(env, term, &head, &tail)) { DMatrixHandle **resource = NULL; - if (!enif_get_resource(env, head, DMatrix_RESOURCE_TYPE, - (void *)&(resource))) { + if (!enif_get_resource(env, head, DMatrix_RESOURCE_TYPE, (void *)&(resource))) { exg_free_dmatrix_list(*dmats); *dmats = NULL; return 0; @@ -194,15 +190,8 @@ static int exg_get_boolean(ErlNifEnv *env, ERL_NIF_TERM term, int *value) { // - Element size: Any positive integer that fits in size_t is accepted syntactically. // XGBoost will validate whether it supports the specific type/width combination. // - The '|' marker is only valid for single-byte types (width 1). -int exg_parse_typestr( - const char *typestr, - size_t *element_size_out, - const char **error_msg -) { - if (typestr == NULL || - typestr[0] == '\0' || - typestr[1] == '\0' || - typestr[2] == '\0') { +int exg_parse_typestr(const char *typestr, size_t *element_size_out, const char **error_msg) { + if (typestr == NULL || typestr[0] == '\0' || typestr[1] == '\0' || typestr[2] == '\0') { *error_msg = "Typestr must have the form ' SIZE_MAX) { + if (errno == ERANGE || end == size_text || *end != '\0' || parsed == 0 || parsed > SIZE_MAX) { *error_msg = "Invalid typestr element size"; return 0; } @@ -258,8 +238,7 @@ int exg_parse_typestr( // The byte-order-independent marker '|' is only valid for single-byte types if (endianness == '|' && element_size != 1) { - *error_msg = - "Byte-order-independent marker '|' is only valid for single-byte types"; + *error_msg = "Byte-order-independent marker '|' is only valid for single-byte types"; return 0; } @@ -268,8 +247,8 @@ int exg_parse_typestr( } // Helper: Build shape JSON string dynamically -static int exg_shape_to_json(ErlNifEnv *env, ERL_NIF_TERM shape_term, - char **json_out, const char **error_msg) { +static int exg_shape_to_json(ErlNifEnv *env, ERL_NIF_TERM shape_term, char **json_out, + const char **error_msg) { unsigned shape_len; char *json = NULL; size_t capacity = 64; @@ -313,10 +292,10 @@ static int exg_shape_to_json(ErlNifEnv *env, ERL_NIF_TERM shape_term, return 0; } - size_t needed = written + (i < shape_len - 1 ? 1 : 0); // +1 for comma + size_t needed = written + (i < shape_len - 1 ? 1 : 0); // +1 for comma // Ensure capacity - while (pos + needed + 2 >= capacity) { // +2 for ']' and '\0' + while (pos + needed + 2 >= capacity) { // +2 for ']' and '\0' capacity *= 2; char *new_json = enif_realloc(json, capacity); if (new_json == NULL) { @@ -345,9 +324,8 @@ static int exg_shape_to_json(ErlNifEnv *env, ERL_NIF_TERM shape_term, } // Helper: Validate shape and check binary size -static int exg_validate_shape_and_size(ErlNifEnv *env, ERL_NIF_TERM shape_term, - size_t element_size, size_t binary_size, - size_t *required_bytes_out, +static int exg_validate_shape_and_size(ErlNifEnv *env, ERL_NIF_TERM shape_term, size_t element_size, + size_t binary_size, size_t *required_bytes_out, const char **error_msg) { unsigned shape_len; @@ -399,12 +377,9 @@ static int exg_validate_shape_and_size(ErlNifEnv *env, ERL_NIF_TERM shape_term, } // Helper: Extract Array Interface components from tuple {binary, typestr, shape, readonly} -int exg_get_array_interface_tuple(ErlNifEnv *env, ERL_NIF_TERM tuple_term, - ERL_NIF_TERM *binary_out, - ERL_NIF_TERM *typestr_out, - ERL_NIF_TERM *shape_out, - ERL_NIF_TERM *readonly_out, - const char **error_msg) { +int exg_get_array_interface_tuple(ErlNifEnv *env, ERL_NIF_TERM tuple_term, ERL_NIF_TERM *binary_out, + ERL_NIF_TERM *typestr_out, ERL_NIF_TERM *shape_out, + ERL_NIF_TERM *readonly_out, const char **error_msg) { int arity = 0; const ERL_NIF_TERM *tuple_elements = NULL; @@ -434,10 +409,9 @@ int exg_get_array_interface_tuple(ErlNifEnv *env, ERL_NIF_TERM tuple_term, // Helper to build Array Interface JSON from components with fresh address // Returns 1 on success, 0 on failure int exg_build_array_interface_json(ErlNifEnv *env, ERL_NIF_TERM binary_term, - ERL_NIF_TERM typestr_term, - ERL_NIF_TERM shape_term, - ERL_NIF_TERM readonly_term, char **json_out, - const char **error_msg) { + ERL_NIF_TERM typestr_term, ERL_NIF_TERM shape_term, + ERL_NIF_TERM readonly_term, char **json_out, + const char **error_msg) { ErlNifBinary data_bin; char *typestr = NULL; char *shape_json = NULL; @@ -474,8 +448,8 @@ int exg_build_array_interface_json(ErlNifEnv *env, ERL_NIF_TERM binary_term, // Validate shape dimensions and binary size size_t required_bytes = 0; - if (!exg_validate_shape_and_size(env, shape_term, element_size, data_bin.size, - &required_bytes, error_msg)) { + if (!exg_validate_shape_and_size(env, shape_term, element_size, data_bin.size, &required_bytes, + error_msg)) { goto CLEANUP; } @@ -491,8 +465,7 @@ int exg_build_array_interface_json(ErlNifEnv *env, ERL_NIF_TERM binary_term, int needed = snprintf(NULL, 0, "{\"typestr\":\"%s\",\"shape\":%s," "\"data\":[%" PRIuPTR ",%s],\"version\":3}", - typestr, shape_json, address, - readonly ? "true" : "false"); + typestr, shape_json, address, readonly ? "true" : "false"); if (needed < 0) { *error_msg = "Failed to calculate JSON size"; @@ -510,8 +483,7 @@ int exg_build_array_interface_json(ErlNifEnv *env, ERL_NIF_TERM binary_term, int written = snprintf(json, (size_t)needed + 1, "{\"typestr\":\"%s\",\"shape\":%s," "\"data\":[%" PRIuPTR ",%s],\"version\":3}", - typestr, shape_json, address, - readonly ? "true" : "false"); + typestr, shape_json, address, readonly ? "true" : "false"); if (written != needed) { *error_msg = "Failed to construct array interface JSON"; @@ -539,8 +511,7 @@ int exg_build_array_interface_json(ErlNifEnv *env, ERL_NIF_TERM binary_term, return ok; } -ERL_NIF_TERM exg_get_int_size(ErlNifEnv *env, int argc, - const ERL_NIF_TERM argv[]) { +ERL_NIF_TERM exg_get_int_size(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { ERL_NIF_TERM ret = 0; if (argc != 0) { ret = exg_error(env, "exg_get_int_size doesn't take any arguments"); @@ -553,30 +524,12 @@ ERL_NIF_TERM exg_get_int_size(ErlNifEnv *env, int argc, } // So we don't expose ATOM_* directly to other files, provide a wrapper function. -int exg_make_array_interface_map( - ErlNifEnv *env, - ERL_NIF_TERM binary_term, - ERL_NIF_TERM typestr_term, - ERL_NIF_TERM shape_term, - ERL_NIF_TERM *out_map -) { - ERL_NIF_TERM keys[] = { - ATOM_BINARY, - ATOM_TYPESTR, - ATOM_SHAPE - }; - - ERL_NIF_TERM values[] = { - binary_term, - typestr_term, - shape_term - }; - - return enif_make_map_from_arrays( - env, - keys, - values, - 3, - out_map - ); +int exg_make_array_interface_map(ErlNifEnv *env, ERL_NIF_TERM binary_term, + ERL_NIF_TERM typestr_term, ERL_NIF_TERM shape_term, + ERL_NIF_TERM *out_map) { + ERL_NIF_TERM keys[] = {ATOM_BINARY, ATOM_TYPESTR, ATOM_SHAPE}; + + ERL_NIF_TERM values[] = {binary_term, typestr_term, shape_term}; + + return enif_make_map_from_arrays(env, keys, values, 3, out_map); } \ No newline at end of file