http://git-wip-us.apache.org/repos/asf/ignite/blob/4ae29fca/modules/ml/xgboost-model-parser/src/main/java/org/apache/ignite/ml/xgboost/parser/XGBoostModelParser.java ---------------------------------------------------------------------- diff --git a/modules/ml/xgboost-model-parser/src/main/java/org/apache/ignite/ml/xgboost/parser/XGBoostModelParser.java b/modules/ml/xgboost-model-parser/src/main/java/org/apache/ignite/ml/xgboost/parser/XGBoostModelParser.java new file mode 100644 index 0000000..e202eba --- /dev/null +++ b/modules/ml/xgboost-model-parser/src/main/java/org/apache/ignite/ml/xgboost/parser/XGBoostModelParser.java @@ -0,0 +1,966 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.ml.xgboost.parser; + +import java.util.List; +import org.antlr.v4.runtime.NoViableAltException; +import org.antlr.v4.runtime.Parser; +import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.RecognitionException; +import org.antlr.v4.runtime.RuntimeMetaData; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.TokenStream; +import org.antlr.v4.runtime.Vocabulary; +import org.antlr.v4.runtime.VocabularyImpl; +import org.antlr.v4.runtime.atn.ATN; +import org.antlr.v4.runtime.atn.ATNDeserializer; +import org.antlr.v4.runtime.atn.ParserATNSimulator; +import org.antlr.v4.runtime.atn.PredictionContextCache; +import org.antlr.v4.runtime.dfa.DFA; +import org.antlr.v4.runtime.tree.ParseTreeListener; +import org.antlr.v4.runtime.tree.ParseTreeVisitor; +import org.antlr.v4.runtime.tree.TerminalNode; + +/** + * XGBoost model parser generated by ANTLR. + */ +@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"}) +public class XGBoostModelParser extends Parser { + /** ANTLR version checker. */ + static { + RuntimeMetaData.checkVersion("4.7.1", RuntimeMetaData.VERSION); + } + + /** DFA. */ + protected static final DFA[] _decisionToDFA; + + /** Shared context cache. */ + protected static final PredictionContextCache _sharedContextCache = new PredictionContextCache(); + + /** */ + public static final int + YES = 1, NO = 2, MISSING = 3, EQ = 4, COMMA = 5, PLUS = 6, MINUS = 7, DOT = 8, EXP = 9, + BOOSTER = 10, LBRACK = 11, RBRACK = 12, COLON = 13, LEAF = 14, INT = 15, DOUBLE = 16, + STRING = 17, NEWLINE = 18, LT = 19, WS = 20; + + /** */ + public static final int + RULE_xgValue = 0, RULE_xgHeader = 1, RULE_xgNode = 2, RULE_xgLeaf = 3, + RULE_xgTree = 4, RULE_xgModel = 5; + + /** Rule names. */ + public static final String[] ruleNames = { + "xgValue", "xgHeader", "xgNode", "xgLeaf", "xgTree", "xgModel" + }; + + /** Literal names. */ + private static final String[] _LITERAL_NAMES = { + null, "'yes'", "'no'", "'missing'", "'='", "','", "'+'", "'-'", "'.'", + null, "'booster'", "'['", "']'", "':'", "'leaf'", null, null, null, null, + "'<'" + }; + + /** Symbolic names. */ + private static final String[] _SYMBOLIC_NAMES = { + null, "YES", "NO", "MISSING", "EQ", "COMMA", "PLUS", "MINUS", "DOT", "EXP", + "BOOSTER", "LBRACK", "RBRACK", "COLON", "LEAF", "INT", "DOUBLE", "STRING", + "NEWLINE", "LT", "WS" + }; + + /** Vocabulary. */ + public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); + + /** + * Token names. + * + * @deprecated Use {@link #VOCABULARY} instead. + */ + @Deprecated + public static final String[] tokenNames; + + /** */ + static { + tokenNames = new String[_SYMBOLIC_NAMES.length]; + for (int i = 0; i < tokenNames.length; i++) { + tokenNames[i] = VOCABULARY.getLiteralName(i); + if (tokenNames[i] == null) { + tokenNames[i] = VOCABULARY.getSymbolicName(i); + } + + if (tokenNames[i] == null) { + tokenNames[i] = "<INVALID>"; + } + } + } + + /** {@inheritDoc} */ + @Deprecated + @Override public String[] getTokenNames() { + return tokenNames; + } + + /** {@inheritDoc} */ + @Override public Vocabulary getVocabulary() { + return VOCABULARY; + } + + /** {@inheritDoc} */ + @Override public String getGrammarFileName() { + return "XGBoostModel.g4"; + } + + /** {@inheritDoc} */ + @Override public String[] getRuleNames() { + return ruleNames; + } + + /** {@inheritDoc} */ + @Override public String getSerializedATN() { + return _serializedATN; + } + + /** {@inheritDoc} */ + @Override public ATN getATN() { + return _ATN; + } + + /** + * Constructs a new instance of XGBoost model parser. + * + * @param input Token stream. + */ + public XGBoostModelParser(TokenStream input) { + super(input); + _interp = new ParserATNSimulator(this, _ATN, _decisionToDFA, _sharedContextCache); + } + + /** + * XG value context. + */ + public static class XgValueContext extends ParserRuleContext { + /** */ + public TerminalNode DOUBLE() { + return getToken(XGBoostModelParser.DOUBLE, 0); + } + + /** */ + public TerminalNode INT() { + return getToken(XGBoostModelParser.INT, 0); + } + + /** + * Constructs a new instance of XG value context. + * + * @param parent Parent. + * @param invokingState Invoking state. + */ + public XgValueContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + + /** {@inheritDoc} */ + @Override public int getRuleIndex() { + return RULE_xgValue; + } + + /** {@inheritDoc} */ + @Override public void enterRule(ParseTreeListener listener) { + if (listener instanceof XGBoostModelListener) + ((XGBoostModelListener)listener).enterXgValue(this); + } + + /** {@inheritDoc} */ + @Override public void exitRule(ParseTreeListener listener) { + if (listener instanceof XGBoostModelListener) + ((XGBoostModelListener)listener).exitXgValue(this); + } + + /** {@inheritDoc} */ + @Override public <T> T accept(ParseTreeVisitor<? extends T> visitor) { + if (visitor instanceof XGBoostModelVisitor) + return ((XGBoostModelVisitor<? extends T>)visitor).visitXgValue(this); + else + return visitor.visitChildren(this); + } + } + + /** + * Returns XG value. + * + * @return XG value. + * @throws RecognitionException In case of exception. + */ + public final XgValueContext xgValue() throws RecognitionException { + XgValueContext _localctx = new XgValueContext(_ctx, getState()); + enterRule(_localctx, 0, RULE_xgValue); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(12); + _la = _input.LA(1); + if (!(_la == INT || _la == DOUBLE)) { + _errHandler.recoverInline(this); + } + else { + if (_input.LA(1) == Token.EOF) + matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + /** + * XG header context. + */ + public static class XgHeaderContext extends ParserRuleContext { + /** */ + public TerminalNode BOOSTER() { + return getToken(XGBoostModelParser.BOOSTER, 0); + } + + /** */ + public TerminalNode LBRACK() { + return getToken(XGBoostModelParser.LBRACK, 0); + } + + /** */ + public TerminalNode INT() { + return getToken(XGBoostModelParser.INT, 0); + } + + /** */ + public TerminalNode RBRACK() { + return getToken(XGBoostModelParser.RBRACK, 0); + } + + /** */ + public TerminalNode COLON() { + return getToken(XGBoostModelParser.COLON, 0); + } + + /** + * Constructs a new instance of XG header context. + * + * @param parent Parent. + * @param invokingState Invoking state. + */ + public XgHeaderContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + + /** {@inheritDoc} */ + @Override public int getRuleIndex() { + return RULE_xgHeader; + } + + /** {@inheritDoc} */ + @Override public void enterRule(ParseTreeListener listener) { + if (listener instanceof XGBoostModelListener) + ((XGBoostModelListener)listener).enterXgHeader(this); + } + + /** {@inheritDoc} */ + @Override public void exitRule(ParseTreeListener listener) { + if (listener instanceof XGBoostModelListener) + ((XGBoostModelListener)listener).exitXgHeader(this); + } + + /** {@inheritDoc} */ + @Override public <T> T accept(ParseTreeVisitor<? extends T> visitor) { + if (visitor instanceof XGBoostModelVisitor) + return ((XGBoostModelVisitor<? extends T>)visitor).visitXgHeader(this); + else + return visitor.visitChildren(this); + } + } + + /** + * Returns XG header. + * + * @return XG header. + * @throws RecognitionException In case of exception. + */ + public final XgHeaderContext xgHeader() throws RecognitionException { + XgHeaderContext _localctx = new XgHeaderContext(_ctx, getState()); + enterRule(_localctx, 2, RULE_xgHeader); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(14); + match(BOOSTER); + setState(15); + match(LBRACK); + setState(16); + match(INT); + setState(17); + match(RBRACK); + setState(19); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la == COLON) { + { + setState(18); + match(COLON); + } + } + + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + /** + * XG node conext. + */ + public static class XgNodeContext extends ParserRuleContext { + /** */ + public List<TerminalNode> INT() { + return getTokens(XGBoostModelParser.INT); + } + + /** */ + public TerminalNode INT(int i) { + return getToken(XGBoostModelParser.INT, i); + } + + /** */ + public TerminalNode COLON() { + return getToken(XGBoostModelParser.COLON, 0); + } + + /** */ + public TerminalNode LBRACK() { + return getToken(XGBoostModelParser.LBRACK, 0); + } + + /** */ + public TerminalNode STRING() { + return getToken(XGBoostModelParser.STRING, 0); + } + + /** */ + public TerminalNode LT() { + return getToken(XGBoostModelParser.LT, 0); + } + + /** */ + public XgValueContext xgValue() { + return getRuleContext(XgValueContext.class, 0); + } + + /** */ + public TerminalNode RBRACK() { + return getToken(XGBoostModelParser.RBRACK, 0); + } + + /** */ + public TerminalNode YES() { + return getToken(XGBoostModelParser.YES, 0); + } + + /** */ + public List<TerminalNode> EQ() { + return getTokens(XGBoostModelParser.EQ); + } + + /** */ + public TerminalNode EQ(int i) { + return getToken(XGBoostModelParser.EQ, i); + } + + /** */ + public List<TerminalNode> COMMA() { + return getTokens(XGBoostModelParser.COMMA); + } + + /** */ + public TerminalNode COMMA(int i) { + return getToken(XGBoostModelParser.COMMA, i); + } + + /** */ + public TerminalNode NO() { + return getToken(XGBoostModelParser.NO, 0); + } + + /** */ + public TerminalNode MISSING() { + return getToken(XGBoostModelParser.MISSING, 0); + } + + /** + * Constructs a new instance of XG node context. + * + * @param parent Parent. + * @param invokingState Invoking state. + */ + public XgNodeContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + + /** {@inheritDoc} */ + @Override public int getRuleIndex() { + return RULE_xgNode; + } + + /** {@inheritDoc} */ + @Override public void enterRule(ParseTreeListener listener) { + if (listener instanceof XGBoostModelListener) + ((XGBoostModelListener)listener).enterXgNode(this); + } + + /** {@inheritDoc} */ + @Override public void exitRule(ParseTreeListener listener) { + if (listener instanceof XGBoostModelListener) + ((XGBoostModelListener)listener).exitXgNode(this); + } + + /** {@inheritDoc} */ + @Override public <T> T accept(ParseTreeVisitor<? extends T> visitor) { + if (visitor instanceof XGBoostModelVisitor) + return ((XGBoostModelVisitor<? extends T>)visitor).visitXgNode(this); + else + return visitor.visitChildren(this); + } + } + + /** + * Returns XG node. + * + * @return XG node. + * @throws RecognitionException In case of exception. + */ + public final XgNodeContext xgNode() throws RecognitionException { + XgNodeContext _localctx = new XgNodeContext(_ctx, getState()); + enterRule(_localctx, 4, RULE_xgNode); + try { + enterOuterAlt(_localctx, 1); + { + setState(21); + match(INT); + setState(22); + match(COLON); + setState(23); + match(LBRACK); + setState(24); + match(STRING); + setState(25); + match(LT); + setState(26); + xgValue(); + setState(27); + match(RBRACK); + setState(28); + match(YES); + setState(29); + match(EQ); + setState(30); + match(INT); + setState(31); + match(COMMA); + setState(32); + match(NO); + setState(33); + match(EQ); + setState(34); + match(INT); + setState(35); + match(COMMA); + setState(36); + match(MISSING); + setState(37); + match(EQ); + setState(38); + match(INT); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + /** + * XG leaf context. + */ + public static class XgLeafContext extends ParserRuleContext { + /** */ + public TerminalNode INT() { + return getToken(XGBoostModelParser.INT, 0); + } + + /** */ + public TerminalNode COLON() { + return getToken(XGBoostModelParser.COLON, 0); + } + + /** */ + public TerminalNode LEAF() { + return getToken(XGBoostModelParser.LEAF, 0); + } + + /** */ + public TerminalNode EQ() { + return getToken(XGBoostModelParser.EQ, 0); + } + + /** */ + public XgValueContext xgValue() { + return getRuleContext(XgValueContext.class, 0); + } + + /** + * Constructs a new instance of XG leaf conext. + * + * @param parent Parent. + * @param invokingState Invoking state. + */ + public XgLeafContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + + /** {@inheritDoc} */ + @Override public int getRuleIndex() { + return RULE_xgLeaf; + } + + /** {@inheritDoc} */ + @Override public void enterRule(ParseTreeListener listener) { + if (listener instanceof XGBoostModelListener) + ((XGBoostModelListener)listener).enterXgLeaf(this); + } + + /** {@inheritDoc} */ + @Override public void exitRule(ParseTreeListener listener) { + if (listener instanceof XGBoostModelListener) + ((XGBoostModelListener)listener).exitXgLeaf(this); + } + + /** {@inheritDoc} */ + @Override public <T> T accept(ParseTreeVisitor<? extends T> visitor) { + if (visitor instanceof XGBoostModelVisitor) + return ((XGBoostModelVisitor<? extends T>)visitor).visitXgLeaf(this); + else + return visitor.visitChildren(this); + } + } + + /** + * Returns XG leaf. + * + * @return XG leaf. + * @throws RecognitionException In case of exception. + */ + public final XgLeafContext xgLeaf() throws RecognitionException { + XgLeafContext _localctx = new XgLeafContext(_ctx, getState()); + enterRule(_localctx, 6, RULE_xgLeaf); + try { + enterOuterAlt(_localctx, 1); + { + setState(40); + match(INT); + setState(41); + match(COLON); + setState(42); + match(LEAF); + setState(43); + match(EQ); + setState(44); + xgValue(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + /** + * XG tree context. + */ + public static class XgTreeContext extends ParserRuleContext { + /** */ + public XgHeaderContext xgHeader() { + return getRuleContext(XgHeaderContext.class, 0); + } + + /** */ + public List<TerminalNode> NEWLINE() { + return getTokens(XGBoostModelParser.NEWLINE); + } + + /** */ + public TerminalNode NEWLINE(int i) { + return getToken(XGBoostModelParser.NEWLINE, i); + } + + /** */ + public TerminalNode EOF() { + return getToken(XGBoostModelParser.EOF, 0); + } + + /** */ + public List<XgLeafContext> xgLeaf() { + return getRuleContexts(XgLeafContext.class); + } + + /** */ + public XgLeafContext xgLeaf(int i) { + return getRuleContext(XgLeafContext.class, i); + } + + /** */ + public List<XgNodeContext> xgNode() { + return getRuleContexts(XgNodeContext.class); + } + + /** */ + public XgNodeContext xgNode(int i) { + return getRuleContext(XgNodeContext.class, i); + } + + /** + * Constructs a new instance of XG tree context. + * + * @param parent Parent. + * @param invokingState Invoking state. + */ + public XgTreeContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + + /** {@inheritDoc} */ + @Override public int getRuleIndex() { + return RULE_xgTree; + } + + /** {@inheritDoc} */ + @Override public void enterRule(ParseTreeListener listener) { + if (listener instanceof XGBoostModelListener) + ((XGBoostModelListener)listener).enterXgTree(this); + } + + /** {@inheritDoc} */ + @Override public void exitRule(ParseTreeListener listener) { + if (listener instanceof XGBoostModelListener) + ((XGBoostModelListener)listener).exitXgTree(this); + } + + /** {@inheritDoc} */ + @Override public <T> T accept(ParseTreeVisitor<? extends T> visitor) { + if (visitor instanceof XGBoostModelVisitor) + return ((XGBoostModelVisitor<? extends T>)visitor).visitXgTree(this); + else + return visitor.visitChildren(this); + } + } + + /** */ + public final XgTreeContext xgTree() throws RecognitionException { + XgTreeContext _localctx = new XgTreeContext(_ctx, getState()); + enterRule(_localctx, 8, RULE_xgTree); + int _la; + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(46); + xgHeader(); + setState(47); + match(NEWLINE); + setState(83); + _errHandler.sync(this); + switch (getInterpreter().adaptivePredict(_input, 8, _ctx)) { + case 1: { + setState(54); + _errHandler.sync(this); + _alt = 1; + do { + switch (_alt) { + case 1: { + { + setState(50); + _errHandler.sync(this); + switch (getInterpreter().adaptivePredict(_input, 1, _ctx)) { + case 1: { + setState(48); + xgLeaf(); + } + break; + case 2: { + setState(49); + xgNode(); + } + break; + } + setState(52); + match(NEWLINE); + } + } + break; + default: + throw new NoViableAltException(this); + } + setState(56); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input, 2, _ctx); + } + while (_alt != 2 && _alt != org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER); + setState(64); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la == INT) { + { + setState(60); + _errHandler.sync(this); + switch (getInterpreter().adaptivePredict(_input, 3, _ctx)) { + case 1: { + setState(58); + xgLeaf(); + } + break; + case 2: { + setState(59); + xgNode(); + } + break; + } + setState(62); + match(EOF); + } + } + + } + break; + case 2: { + setState(74); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input, 6, _ctx); + while (_alt != 2 && _alt != org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER) { + if (_alt == 1) { + { + { + setState(68); + _errHandler.sync(this); + switch (getInterpreter().adaptivePredict(_input, 5, _ctx)) { + case 1: { + setState(66); + xgLeaf(); + } + break; + case 2: { + setState(67); + xgNode(); + } + break; + } + setState(70); + match(NEWLINE); + } + } + } + setState(76); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input, 6, _ctx); + } + setState(79); + _errHandler.sync(this); + switch (getInterpreter().adaptivePredict(_input, 7, _ctx)) { + case 1: { + setState(77); + xgLeaf(); + } + break; + case 2: { + setState(78); + xgNode(); + } + break; + } + setState(81); + match(EOF); + } + break; + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + /** + * XG model context. + */ + public static class XgModelContext extends ParserRuleContext { + /** */ + public List<XgTreeContext> xgTree() { + return getRuleContexts(XgTreeContext.class); + } + + /** */ + public XgTreeContext xgTree(int i) { + return getRuleContext(XgTreeContext.class, i); + } + + /** + * Constructs a new instance of XG model context. + * + * @param parent Parent. + * @param invokingState Invoking state. + */ + public XgModelContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + + /** {@inheritDoc} */ + @Override public int getRuleIndex() { + return RULE_xgModel; + } + + /** {@inheritDoc} */ + @Override public void enterRule(ParseTreeListener listener) { + if (listener instanceof XGBoostModelListener) + ((XGBoostModelListener)listener).enterXgModel(this); + } + + /** {@inheritDoc} */ + @Override public void exitRule(ParseTreeListener listener) { + if (listener instanceof XGBoostModelListener) + ((XGBoostModelListener)listener).exitXgModel(this); + } + + /** {@inheritDoc} */ + @Override public <T> T accept(ParseTreeVisitor<? extends T> visitor) { + if (visitor instanceof XGBoostModelVisitor) + return ((XGBoostModelVisitor<? extends T>)visitor).visitXgModel(this); + else + return visitor.visitChildren(this); + } + } + + /** */ + public final XgModelContext xgModel() throws RecognitionException { + XgModelContext _localctx = new XgModelContext(_ctx, getState()); + enterRule(_localctx, 10, RULE_xgModel); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(86); + _errHandler.sync(this); + _la = _input.LA(1); + do { + { + { + setState(85); + xgTree(); + } + } + setState(88); + _errHandler.sync(this); + _la = _input.LA(1); + } + while (_la == BOOSTER); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + /** Serialized ATN. */ + public static final String _serializedATN = + "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3\26]\4\2\t\2\4\3\t" + + "\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\3\2\3\2\3\3\3\3\3\3\3\3\3\3\5\3\26" + + "\n\3\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3" + + "\4\3\4\3\4\3\5\3\5\3\5\3\5\3\5\3\5\3\6\3\6\3\6\3\6\5\6\65\n\6\3\6\3\6" + + "\6\69\n\6\r\6\16\6:\3\6\3\6\5\6?\n\6\3\6\3\6\5\6C\n\6\3\6\3\6\5\6G\n\6" + + "\3\6\3\6\7\6K\n\6\f\6\16\6N\13\6\3\6\3\6\5\6R\n\6\3\6\3\6\5\6V\n\6\3\7" + + "\6\7Y\n\7\r\7\16\7Z\3\7\2\2\b\2\4\6\b\n\f\2\3\3\2\21\22\2`\2\16\3\2\2" + + "\2\4\20\3\2\2\2\6\27\3\2\2\2\b*\3\2\2\2\n\60\3\2\2\2\fX\3\2\2\2\16\17" + + "\t\2\2\2\17\3\3\2\2\2\20\21\7\f\2\2\21\22\7\r\2\2\22\23\7\21\2\2\23\25" + + "\7\16\2\2\24\26\7\17\2\2\25\24\3\2\2\2\25\26\3\2\2\2\26\5\3\2\2\2\27\30" + + "\7\21\2\2\30\31\7\17\2\2\31\32\7\r\2\2\32\33\7\23\2\2\33\34\7\25\2\2\34" + + "\35\5\2\2\2\35\36\7\16\2\2\36\37\7\3\2\2\37 \7\6\2\2 !\7\21\2\2!\"\7\7" + + "\2\2\"#\7\4\2\2#$\7\6\2\2$%\7\21\2\2%&\7\7\2\2&\'\7\5\2\2\'(\7\6\2\2(" + + ")\7\21\2\2)\7\3\2\2\2*+\7\21\2\2+,\7\17\2\2,-\7\20\2\2-.\7\6\2\2./\5\2" + + "\2\2/\t\3\2\2\2\60\61\5\4\3\2\61U\7\24\2\2\62\65\5\b\5\2\63\65\5\6\4\2" + + "\64\62\3\2\2\2\64\63\3\2\2\2\65\66\3\2\2\2\66\67\7\24\2\2\679\3\2\2\2" + + "8\64\3\2\2\29:\3\2\2\2:8\3\2\2\2:;\3\2\2\2;B\3\2\2\2<?\5\b\5\2=?\5\6\4" + + "\2><\3\2\2\2>=\3\2\2\2?@\3\2\2\2@A\7\2\2\3AC\3\2\2\2B>\3\2\2\2BC\3\2\2" + + "\2CV\3\2\2\2DG\5\b\5\2EG\5\6\4\2FD\3\2\2\2FE\3\2\2\2GH\3\2\2\2HI\7\24" + + "\2\2IK\3\2\2\2JF\3\2\2\2KN\3\2\2\2LJ\3\2\2\2LM\3\2\2\2MQ\3\2\2\2NL\3\2" + + "\2\2OR\5\b\5\2PR\5\6\4\2QO\3\2\2\2QP\3\2\2\2RS\3\2\2\2ST\7\2\2\3TV\3\2" + + "\2\2U8\3\2\2\2UL\3\2\2\2V\13\3\2\2\2WY\5\n\6\2XW\3\2\2\2YZ\3\2\2\2ZX\3" + + "\2\2\2Z[\3\2\2\2[\r\3\2\2\2\f\25\64:>BFLQUZ"; + + /** ATN. */ + public static final ATN _ATN = new ATNDeserializer().deserialize(_serializedATN.toCharArray()); + + /** */ + static { + _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; + for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) { + _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); + } + } +} \ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/4ae29fca/modules/ml/xgboost-model-parser/src/main/java/org/apache/ignite/ml/xgboost/parser/XGBoostModelVisitor.java ---------------------------------------------------------------------- diff --git a/modules/ml/xgboost-model-parser/src/main/java/org/apache/ignite/ml/xgboost/parser/XGBoostModelVisitor.java b/modules/ml/xgboost-model-parser/src/main/java/org/apache/ignite/ml/xgboost/parser/XGBoostModelVisitor.java new file mode 100644 index 0000000..68621d6 --- /dev/null +++ b/modules/ml/xgboost-model-parser/src/main/java/org/apache/ignite/ml/xgboost/parser/XGBoostModelVisitor.java @@ -0,0 +1,71 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.ml.xgboost.parser; + +import org.antlr.v4.runtime.tree.ParseTreeVisitor; + +/** + * This interface defines a complete generic visitor for a parse tree produced + * by {@link XGBoostModelParser}. + * + * @param <T> The return type of the visit operation. Use {@link Void} for + * operations with no return type. + */ +public interface XGBoostModelVisitor<T> extends ParseTreeVisitor<T> { + /** + * Visit a parse tree produced by {@link XGBoostModelParser#xgValue}. + * @param ctx the parse tree + * @return the visitor result + */ + public T visitXgValue(XGBoostModelParser.XgValueContext ctx); + + /** + * Visit a parse tree produced by {@link XGBoostModelParser#xgHeader}. + * @param ctx the parse tree + * @return the visitor result + */ + public T visitXgHeader(XGBoostModelParser.XgHeaderContext ctx); + + /** + * Visit a parse tree produced by {@link XGBoostModelParser#xgNode}. + * @param ctx the parse tree + * @return the visitor result + */ + public T visitXgNode(XGBoostModelParser.XgNodeContext ctx); + + /** + * Visit a parse tree produced by {@link XGBoostModelParser#xgLeaf}. + * @param ctx the parse tree + * @return the visitor result + */ + public T visitXgLeaf(XGBoostModelParser.XgLeafContext ctx); + + /** + * Visit a parse tree produced by {@link XGBoostModelParser#xgTree}. + * @param ctx the parse tree + * @return the visitor result + */ + public T visitXgTree(XGBoostModelParser.XgTreeContext ctx); + + /** + * Visit a parse tree produced by {@link XGBoostModelParser#xgModel}. + * @param ctx the parse tree + * @return the visitor result + */ + public T visitXgModel(XGBoostModelParser.XgModelContext ctx); +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/4ae29fca/modules/ml/xgboost-model-parser/src/main/java/org/apache/ignite/ml/xgboost/parser/XGModelParser.java ---------------------------------------------------------------------- diff --git a/modules/ml/xgboost-model-parser/src/main/java/org/apache/ignite/ml/xgboost/parser/XGModelParser.java b/modules/ml/xgboost-model-parser/src/main/java/org/apache/ignite/ml/xgboost/parser/XGModelParser.java new file mode 100644 index 0000000..a0b124f --- /dev/null +++ b/modules/ml/xgboost-model-parser/src/main/java/org/apache/ignite/ml/xgboost/parser/XGModelParser.java @@ -0,0 +1,87 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.ml.xgboost.parser; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.CharStreams; +import org.antlr.v4.runtime.CommonTokenStream; +import org.apache.ignite.ml.inference.parser.InfModelParser; +import org.apache.ignite.ml.xgboost.XGModel; +import org.apache.ignite.ml.xgboost.XGObject; +import org.apache.ignite.ml.xgboost.parser.visitor.XGModelVisitor; + +/** XGBoost model parser. Uses the following ANTLR grammar to parse file: + * <pre> + * grammar XGBoostModel; + * + * YES : 'yes' ; + * NO : 'no' ; + * MISSING : 'missing' ; + * EQ : '=' ; + * COMMA : ',' ; + * PLUS : '+' ; + * MINUS : '-' ; + * DOT : '.' ; + * EXP : 'E' | 'e' ; + * BOOSTER : 'booster' ; + * LBRACK : '[' ; + * RBRACK : ']' ; + * COLON : ':' ; + * LEAF : 'leaf' ; + * INT : (PLUS | MINUS)? [0-9]+ ; + * DOUBLE : INT DOT [0-9]* (EXP INT)?; + * STRING : [A-Za-z_][0-9A-Za-z_]+ ; + * NEWLINE : '\r' '\n' | '\n' | '\r' ; + * LT : '<' ; + * WS : ( ' ' | '\t' )+ -> skip ; + * + * xgValue : DOUBLE | INT ; + * xgHeader : BOOSTER LBRACK INT RBRACK COLON? ; + * xgNode : INT COLON LBRACK STRING LT xgValue RBRACK YES EQ INT COMMA NO EQ INT COMMA MISSING EQ INT ; + * xgLeaf : INT COLON LEAF EQ xgValue ; + * xgTree : xgHeader NEWLINE ( + * ((xgLeaf | xgNode) NEWLINE)+ ((xgLeaf | xgNode) EOF)? + * | ((xgLeaf | xgNode) NEWLINE)* (xgLeaf | xgNode) EOF + * ) ; + * xgModel : xgTree+ ; + * </pre> + */ +// TODO: IGNITE-10718 Merge XGBoost and Ignite ML trees together. +public class XGModelParser implements InfModelParser<XGObject, Double> { + /** */ + private static final long serialVersionUID = -5819843559270294718L; + + /** {@inheritDoc} */ + @Override public XGModel parse(byte[] mdl) { + try (ByteArrayInputStream bais = new ByteArrayInputStream(mdl)) { + CharStream cStream = CharStreams.fromStream(bais); + XGBoostModelLexer lexer = new XGBoostModelLexer(cStream); + CommonTokenStream tokens = new CommonTokenStream(lexer); + XGBoostModelParser parser = new XGBoostModelParser(tokens); + + XGModelVisitor visitor = new XGModelVisitor(); + + return visitor.visit(parser.xgModel()); + } + catch (IOException e) { + throw new RuntimeException(e); + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/4ae29fca/modules/ml/xgboost-model-parser/src/main/java/org/apache/ignite/ml/xgboost/parser/package-info.java ---------------------------------------------------------------------- diff --git a/modules/ml/xgboost-model-parser/src/main/java/org/apache/ignite/ml/xgboost/parser/package-info.java b/modules/ml/xgboost-model-parser/src/main/java/org/apache/ignite/ml/xgboost/parser/package-info.java new file mode 100644 index 0000000..959b3ba --- /dev/null +++ b/modules/ml/xgboost-model-parser/src/main/java/org/apache/ignite/ml/xgboost/parser/package-info.java @@ -0,0 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * <!-- Package description. --> + * Base package for XGBoost model parser implementation. + */ +package org.apache.ignite.ml.xgboost.parser; \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/4ae29fca/modules/ml/xgboost-model-parser/src/main/java/org/apache/ignite/ml/xgboost/parser/visitor/XGModelVisitor.java ---------------------------------------------------------------------- diff --git a/modules/ml/xgboost-model-parser/src/main/java/org/apache/ignite/ml/xgboost/parser/visitor/XGModelVisitor.java b/modules/ml/xgboost-model-parser/src/main/java/org/apache/ignite/ml/xgboost/parser/visitor/XGModelVisitor.java new file mode 100644 index 0000000..70433c7 --- /dev/null +++ b/modules/ml/xgboost-model-parser/src/main/java/org/apache/ignite/ml/xgboost/parser/visitor/XGModelVisitor.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.ml.xgboost.parser.visitor; + +import java.util.ArrayList; +import java.util.List; +import org.apache.ignite.ml.xgboost.XGModel; +import org.apache.ignite.ml.xgboost.XGNode; +import org.apache.ignite.ml.xgboost.parser.XGBoostModelBaseVisitor; +import org.apache.ignite.ml.xgboost.parser.XGBoostModelParser; + +/** + * XGBoost model visitor that parses model. + */ +public class XGModelVisitor extends XGBoostModelBaseVisitor<XGModel> { + /** Tree visitor. */ + private final XGTreeVisitor treeVisitor = new XGTreeVisitor(); + + /** {@inheritDoc} */ + @Override public XGModel visitXgModel(XGBoostModelParser.XgModelContext ctx) { + List<XGNode> trees = new ArrayList<>(); + + for (XGBoostModelParser.XgTreeContext treeCtx : ctx.xgTree()) + trees.add(treeVisitor.visitXgTree(treeCtx)); + + return new XGModel(trees); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/4ae29fca/modules/ml/xgboost-model-parser/src/main/java/org/apache/ignite/ml/xgboost/parser/visitor/XGTreeVisitor.java ---------------------------------------------------------------------- diff --git a/modules/ml/xgboost-model-parser/src/main/java/org/apache/ignite/ml/xgboost/parser/visitor/XGTreeVisitor.java b/modules/ml/xgboost-model-parser/src/main/java/org/apache/ignite/ml/xgboost/parser/visitor/XGTreeVisitor.java new file mode 100644 index 0000000..60268ff --- /dev/null +++ b/modules/ml/xgboost-model-parser/src/main/java/org/apache/ignite/ml/xgboost/parser/visitor/XGTreeVisitor.java @@ -0,0 +1,82 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.ml.xgboost.parser.visitor; + +import java.util.HashMap; +import java.util.Map; +import org.antlr.v4.runtime.tree.TerminalNode; +import org.apache.ignite.ml.xgboost.XGLeafNode; +import org.apache.ignite.ml.xgboost.XGNode; +import org.apache.ignite.ml.xgboost.XGSplitNode; +import org.apache.ignite.ml.xgboost.parser.XGBoostModelBaseVisitor; +import org.apache.ignite.ml.xgboost.parser.XGBoostModelParser; + +/** + * XGBoost tree visitor that parses tree. + */ +public class XGTreeVisitor extends XGBoostModelBaseVisitor<XGNode> { + /** Index of the root node. */ + private static final int ROOT_NODE_IDX = 0; + + /** {@inheritDoc} */ + @Override public XGNode visitXgTree(XGBoostModelParser.XgTreeContext ctx) { + Map<Integer, XGSplitNode> splitNodes = new HashMap<>(); + Map<Integer, XGLeafNode> leafNodes = new HashMap<>(); + + for (XGBoostModelParser.XgNodeContext nodeCtx : ctx.xgNode()) { + int idx = Integer.valueOf(nodeCtx.INT(0).getText()); + String featureName = nodeCtx.STRING().getText(); + double threshold = parseXgValue(nodeCtx.xgValue()); + + splitNodes.put(idx, new XGSplitNode(featureName, threshold)); + } + + for (XGBoostModelParser.XgLeafContext leafCtx : ctx.xgLeaf()) { + int idx = Integer.valueOf(leafCtx.INT().getText()); + double val = parseXgValue(leafCtx.xgValue()); + + leafNodes.put(idx, new XGLeafNode(val)); + } + + for (XGBoostModelParser.XgNodeContext nodeCtx : ctx.xgNode()) { + int idx = Integer.valueOf(nodeCtx.INT(0).getText()); + int yesIdx = Integer.valueOf(nodeCtx.INT(1).getText()); + int noIdx = Integer.valueOf(nodeCtx.INT(2).getText()); + int missIdx = Integer.valueOf(nodeCtx.INT(3).getText()); + + XGSplitNode node = splitNodes.get(idx); + node.setYesNode(splitNodes.containsKey(yesIdx) ? splitNodes.get(yesIdx) : leafNodes.get(yesIdx)); + node.setNoNode(splitNodes.containsKey(noIdx) ? splitNodes.get(noIdx) : leafNodes.get(noIdx)); + node.setMissingNode(splitNodes.containsKey(missIdx) ? splitNodes.get(missIdx) : leafNodes.get(missIdx)); + } + + return splitNodes.containsKey(ROOT_NODE_IDX) ? splitNodes.get(ROOT_NODE_IDX) : leafNodes.get(ROOT_NODE_IDX); + } + + /** + * Parses value (int of double). + * + * @param valCtx Value context. + * @return Value. + */ + private double parseXgValue(XGBoostModelParser.XgValueContext valCtx) { + TerminalNode terminalNode = valCtx.INT() != null ? valCtx.INT() : valCtx.DOUBLE(); + + return Double.valueOf(terminalNode.getText()); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/4ae29fca/modules/ml/xgboost-model-parser/src/main/java/org/apache/ignite/ml/xgboost/parser/visitor/package-info.java ---------------------------------------------------------------------- diff --git a/modules/ml/xgboost-model-parser/src/main/java/org/apache/ignite/ml/xgboost/parser/visitor/package-info.java b/modules/ml/xgboost-model-parser/src/main/java/org/apache/ignite/ml/xgboost/parser/visitor/package-info.java new file mode 100644 index 0000000..2cb9ce7 --- /dev/null +++ b/modules/ml/xgboost-model-parser/src/main/java/org/apache/ignite/ml/xgboost/parser/visitor/package-info.java @@ -0,0 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * <!-- Package description. --> + * Base package for XGBoost model parser ANTLR visitor. + */ +package org.apache.ignite.ml.xgboost.parser.visitor; \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/4ae29fca/modules/ml/xgboost-model-parser/src/test/java/org/apache/ignite/ml/xgboost/IgniteMLXGBoostTestSuite.java ---------------------------------------------------------------------- diff --git a/modules/ml/xgboost-model-parser/src/test/java/org/apache/ignite/ml/xgboost/IgniteMLXGBoostTestSuite.java b/modules/ml/xgboost-model-parser/src/test/java/org/apache/ignite/ml/xgboost/IgniteMLXGBoostTestSuite.java new file mode 100644 index 0000000..9ccab38 --- /dev/null +++ b/modules/ml/xgboost-model-parser/src/test/java/org/apache/ignite/ml/xgboost/IgniteMLXGBoostTestSuite.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.ml.xgboost; + +import org.apache.ignite.ml.xgboost.parser.XGBoostModelParserTest; +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +/** Test suite for all module tests. */ +@RunWith(Suite.class) [email protected]({ + XGBoostModelParserTest.class +}) +public class IgniteMLXGBoostTestSuite { + // No-op. +} http://git-wip-us.apache.org/repos/asf/ignite/blob/4ae29fca/modules/ml/xgboost-model-parser/src/test/java/org/apache/ignite/ml/xgboost/parser/XGBoostModelParserTest.java ---------------------------------------------------------------------- diff --git a/modules/ml/xgboost-model-parser/src/test/java/org/apache/ignite/ml/xgboost/parser/XGBoostModelParserTest.java b/modules/ml/xgboost-model-parser/src/test/java/org/apache/ignite/ml/xgboost/parser/XGBoostModelParserTest.java new file mode 100644 index 0000000..abee78f --- /dev/null +++ b/modules/ml/xgboost-model-parser/src/test/java/org/apache/ignite/ml/xgboost/parser/XGBoostModelParserTest.java @@ -0,0 +1,85 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.ml.xgboost.parser; + +import java.net.URL; +import java.util.Scanner; +import org.apache.ignite.ml.inference.InfModel; +import org.apache.ignite.ml.inference.builder.SingleInfModelBuilder; +import org.apache.ignite.ml.inference.builder.SyncInfModelBuilder; +import org.apache.ignite.ml.inference.reader.FileSystemInfModelReader; +import org.apache.ignite.ml.inference.reader.InfModelReader; +import org.apache.ignite.ml.xgboost.MapBasedXGObject; +import org.apache.ignite.ml.xgboost.XGObject; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * Tests for {@link XGBoostModelParser}. + */ +public class XGBoostModelParserTest { + /** Test model resource name. */ + private static final String TEST_MODEL_RESOURCE = "datasets/agaricus-model.txt"; + + /** Parser. */ + private final XGModelParser parser = new XGModelParser(); + + /** Model builder. */ + private final SyncInfModelBuilder mdlBuilder = new SingleInfModelBuilder(); + + /** End-to-end test for {@code parse()} and {@code predict()} methods. */ + @Test + public void testParseAndPredict() { + URL url = XGBoostModelParserTest.class.getClassLoader().getResource(TEST_MODEL_RESOURCE); + if (url == null) + throw new IllegalStateException("File not found [resource_name=" + TEST_MODEL_RESOURCE + "]"); + + InfModelReader reader = new FileSystemInfModelReader(url.getPath()); + + try (InfModel<XGObject, Double> mdl = mdlBuilder.build(reader, parser); + Scanner testDataScanner = new Scanner(XGBoostModelParserTest.class.getClassLoader() + .getResourceAsStream("datasets/agaricus-test-data.txt")); + Scanner testExpResultsScanner = new Scanner(XGBoostModelParserTest.class.getClassLoader() + .getResourceAsStream("datasets/agaricus-test-expected-results.txt"))) { + + while (testDataScanner.hasNextLine()) { + assertTrue(testExpResultsScanner.hasNextLine()); + + String testDataStr = testDataScanner.nextLine(); + String testExpResultsStr = testExpResultsScanner.nextLine(); + + MapBasedXGObject testObj = new MapBasedXGObject(); + + for (String keyValueString : testDataStr.split(" ")) { + String[] keyVal = keyValueString.split(":"); + + if (keyVal.length == 2) + testObj.put("f" + keyVal[0], Double.parseDouble(keyVal[1])); + } + + double prediction = mdl.predict(testObj); + + double expPrediction = Double.parseDouble(testExpResultsStr); + + assertEquals(expPrediction, prediction, 1e-6); + } + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/4ae29fca/modules/ml/xgboost-model-parser/src/test/resources/datasets/agaricus-model.txt ---------------------------------------------------------------------- diff --git a/modules/ml/xgboost-model-parser/src/test/resources/datasets/agaricus-model.txt b/modules/ml/xgboost-model-parser/src/test/resources/datasets/agaricus-model.txt new file mode 100644 index 0000000..4bf76d6 --- /dev/null +++ b/modules/ml/xgboost-model-parser/src/test/resources/datasets/agaricus-model.txt @@ -0,0 +1,714 @@ +booster[0]: +0:[f29<-9.53674e-07] yes=1,no=2,missing=1 + 1:[f56<-9.53674e-07] yes=3,no=4,missing=3 + 3:[f60<-9.53674e-07] yes=7,no=8,missing=7 + 7:[f23<-9.53674e-07] yes=13,no=14,missing=13 + 13:[f24<-9.53674e-07] yes=19,no=20,missing=19 + 19:leaf=1.99735 + 20:leaf=-1.8 + 14:leaf=-1.80952 + 8:leaf=-1.95062 + 4:[f21<-9.53674e-07] yes=9,no=10,missing=9 + 9:leaf=1.77778 + 10:leaf=-1.98104 + 2:[f109<-9.53674e-07] yes=5,no=6,missing=5 + 5:[f67<-9.53674e-07] yes=11,no=12,missing=11 + 11:[f8<-9.53674e-07] yes=15,no=16,missing=15 + 15:leaf=-1.99117 + 16:leaf=1 + 12:[f39<-9.53674e-07] yes=17,no=18,missing=17 + 17:leaf=1.77143 + 18:leaf=-1.5 + 6:leaf=1.85965 +booster[1]: +0:[f29<-9.53674e-07] yes=1,no=2,missing=1 + 1:[f21<-9.53674e-07] yes=3,no=4,missing=3 + 3:leaf=1.13207 + 4:[f27<-9.53674e-07] yes=7,no=8,missing=7 + 7:[f30<-9.53674e-07] yes=11,no=12,missing=11 + 11:leaf=-1.12641 + 12:leaf=1.08392 + 8:leaf=1.09118 + 2:[f109<-9.53674e-07] yes=5,no=6,missing=5 + 5:[f67<-9.53674e-07] yes=9,no=10,missing=9 + 9:[f39<-9.53674e-07] yes=13,no=14,missing=13 + 13:[f21<-9.53674e-07] yes=17,no=18,missing=17 + 17:leaf=-1.06692 + 18:leaf=2.08 + 14:leaf=-1.13236 + 10:[f39<-9.53674e-07] yes=15,no=16,missing=15 + 15:leaf=0.928896 + 16:leaf=-0.784694 + 6:leaf=0.994744 +booster[2]: +0:[f29<-9.53674e-07] yes=1,no=2,missing=1 + 1:[f21<-9.53674e-07] yes=3,no=4,missing=3 + 3:leaf=1.03409 + 4:[f27<-9.53674e-07] yes=7,no=8,missing=7 + 7:[f30<-9.53674e-07] yes=11,no=12,missing=11 + 11:leaf=-1.00925 + 12:leaf=0.934041 + 8:leaf=0.947964 + 2:[f109<-9.53674e-07] yes=5,no=6,missing=5 + 5:[f39<-9.53674e-07] yes=9,no=10,missing=9 + 9:[f112<-9.53674e-07] yes=13,no=14,missing=13 + 13:leaf=-0.862367 + 14:[f79<-9.53674e-07] yes=15,no=16,missing=15 + 15:leaf=0.996309 + 16:leaf=-0.217869 + 10:leaf=-1.03467 + 6:leaf=0.773973 +booster[3]: +0:[f29<-9.53674e-07] yes=1,no=2,missing=1 + 1:[f56<-9.53674e-07] yes=3,no=4,missing=3 + 3:[f60<-9.53674e-07] yes=7,no=8,missing=7 + 7:[f36<-9.53674e-07] yes=11,no=12,missing=11 + 11:[f21<-9.53674e-07] yes=15,no=16,missing=15 + 15:leaf=0.535599 + 16:leaf=-0.591832 + 12:leaf=0.99398 + 8:leaf=-0.731796 + 4:leaf=-0.74401 + 2:[f109<-9.53674e-07] yes=5,no=6,missing=5 + 5:[f67<-9.53674e-07] yes=9,no=10,missing=9 + 9:[f115<-9.53674e-07] yes=13,no=14,missing=13 + 13:leaf=-0.991027 + 14:[f86<-9.53674e-07] yes=17,no=18,missing=17 + 17:leaf=-0.71378 + 18:leaf=-0.010833 + 10:leaf=0.382551 + 6:leaf=0.587063 +booster[4]: +0:[f29<-9.53674e-07] yes=1,no=2,missing=1 + 1:[f21<-9.53674e-07] yes=3,no=4,missing=3 + 3:leaf=0.949695 + 4:[f27<-9.53674e-07] yes=7,no=8,missing=7 + 7:[f30<-9.53674e-07] yes=13,no=14,missing=13 + 13:leaf=-0.846263 + 14:leaf=0.571051 + 8:leaf=0.604424 + 2:[f39<-9.53674e-07] yes=5,no=6,missing=5 + 5:[f7<-9.53674e-07] yes=9,no=10,missing=9 + 9:leaf=0.359876 + 10:leaf=-0.0906721 + 6:[f1<-9.53674e-07] yes=11,no=12,missing=11 + 11:leaf=-0.902494 + 12:leaf=-0.222349 +booster[5]: +0:[f29<-9.53674e-07] yes=1,no=2,missing=1 + 1:[f21<-9.53674e-07] yes=3,no=4,missing=3 + 3:leaf=0.866121 + 4:[f56<-9.53674e-07] yes=7,no=8,missing=7 + 7:[f10<-9.53674e-07] yes=11,no=12,missing=11 + 11:leaf=-0.172918 + 12:leaf=0.444059 + 8:leaf=-0.581706 + 2:[f109<-9.53674e-07] yes=5,no=6,missing=5 + 5:[f39<-9.53674e-07] yes=9,no=10,missing=9 + 9:[f65<-9.53674e-07] yes=13,no=14,missing=13 + 13:leaf=0.314289 + 14:leaf=-0.137217 + 10:leaf=-0.87866 + 6:leaf=0.593857 +booster[6]: +0:[f64<-9.53674e-07] yes=1,no=2,missing=1 + 1:[f39<-9.53674e-07] yes=3,no=4,missing=3 + 3:[f21<-9.53674e-07] yes=5,no=6,missing=5 + 5:leaf=-0.16553 + 6:leaf=0.424994 + 4:[f118<-9.53674e-07] yes=7,no=8,missing=7 + 7:leaf=-0.662592 + 8:leaf=0.10184 + 2:leaf=0.647963 +booster[7]: +0:[f27<-9.53674e-07] yes=1,no=2,missing=1 + 1:[f39<-9.53674e-07] yes=3,no=4,missing=3 + 3:[f112<-9.53674e-07] yes=5,no=6,missing=5 + 5:leaf=-0.205397 + 6:[f55<-9.53674e-07] yes=9,no=10,missing=9 + 9:leaf=0.531323 + 10:leaf=0.0411505 + 4:[f95<-9.53674e-07] yes=7,no=8,missing=7 + 7:leaf=0.0893909 + 8:leaf=-0.688257 + 2:leaf=0.62192 +booster[8]: +0:[f29<-9.53674e-07] yes=1,no=2,missing=1 + 1:[f21<-9.53674e-07] yes=3,no=4,missing=3 + 3:leaf=0.559472 + 4:leaf=0.047577 + 2:[f21<-9.53674e-07] yes=5,no=6,missing=5 + 5:leaf=-0.522063 + 6:leaf=0.185313 +booster[9]: +0:[f106<-9.53674e-07] yes=1,no=2,missing=1 + 1:[f36<-9.53674e-07] yes=3,no=4,missing=3 + 3:leaf=-0.106198 + 4:[f29<-9.53674e-07] yes=5,no=6,missing=5 + 5:leaf=0.451254 + 6:leaf=0.0100806 + 2:leaf=-0.265738 +booster[10]: +0:[f39<-9.53674e-07] yes=1,no=2,missing=1 + 1:[f118<-9.53674e-07] yes=3,no=4,missing=3 + 3:leaf=0.411374 + 4:leaf=-0.00392402 + 2:[f118<-9.53674e-07] yes=5,no=6,missing=5 + 5:leaf=-0.370329 + 6:leaf=0.106229 +booster[11]: +0:[f126<-9.53674e-07] yes=1,no=2,missing=1 + 1:[f21<-9.53674e-07] yes=3,no=4,missing=3 + 3:leaf=-0.244834 + 4:leaf=0.393425 + 2:leaf=-0.191846 +booster[12]: +0:[f65<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=0.281915 + 2:[f126<-9.53674e-07] yes=3,no=4,missing=3 + 3:leaf=0.0457934 + 4:leaf=-0.335547 +booster[13]: +0:[f39<-9.53674e-07] yes=1,no=2,missing=1 + 1:[f55<-9.53674e-07] yes=3,no=4,missing=3 + 3:leaf=0.298848 + 4:leaf=-0.0234579 + 2:leaf=-0.211675 +booster[14]: +0:[f29<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=0.180838 + 2:[f21<-9.53674e-07] yes=3,no=4,missing=3 + 3:leaf=-0.28038 + 4:leaf=0.0867539 +booster[15]: +0:[f39<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=0.123414 + 2:leaf=-0.136942 +booster[16]: +0:[f36<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=-0.154724 + 2:[f118<-9.53674e-07] yes=3,no=4,missing=3 + 3:leaf=-0.17891 + 4:leaf=0.28564 +booster[17]: +0:[f29<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=0.1202 + 2:leaf=-0.113537 +booster[18]: +0:[f112<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=-0.0946849 + 2:leaf=0.147314 +booster[19]: +0:[f55<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=-0.128399 + 2:leaf=0.117783 +booster[20]: +0:[f36<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=-0.135164 + 2:[f55<-9.53674e-07] yes=3,no=4,missing=3 + 3:leaf=-0.042949 + 4:leaf=0.173579 +booster[21]: +0:[f39<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=0.0957448 + 2:leaf=-0.104156 +booster[22]: +0:[f29<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=0.0925588 + 2:leaf=-0.0798059 +booster[23]: +0:[f112<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=-0.0830908 + 2:leaf=0.126943 +booster[24]: +0:[f126<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=0.0823832 + 2:leaf=-0.0899369 +booster[25]: +0:[f3<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=0.0589036 + 2:leaf=-0.0851568 +booster[26]: +0:[f29<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=0.0859156 + 2:leaf=-0.0815898 +booster[27]: +0:[f21<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=0.0637587 + 2:leaf=-0.048542 +booster[28]: +0:[f55<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=-0.069489 + 2:leaf=0.058072 +booster[29]: +0:[f36<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=-0.149849 + 2:leaf=0.0984096 +booster[30]: +0:[f112<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=-0.0688469 + 2:leaf=0.0689056 +booster[31]: +0:[f55<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=-0.071993 + 2:leaf=0.0544265 +booster[32]: +0:[f29<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=0.0686437 + 2:leaf=-0.061108 +booster[33]: +0:[f39<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=0.0522195 + 2:leaf=-0.0544709 +booster[34]: +0:[f126<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=0.0445775 + 2:leaf=-0.0612543 +booster[35]: +0:[f112<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=-0.0370941 + 2:leaf=0.0414116 +booster[36]: +0:[f29<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=0.0491957 + 2:leaf=-0.0374184 +booster[37]: +0:[f55<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=-0.0428276 + 2:leaf=0.0362258 +booster[38]: +0:[f21<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=0.038428 + 2:leaf=-0.0331781 +booster[39]: +0:[f36<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=-0.14093 + 2:leaf=0.101744 +booster[40]: +0:[f39<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=0.0443167 + 2:leaf=-0.0668384 +booster[41]: +0:[f55<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=-0.0654174 + 2:leaf=0.0401212 +booster[42]: +0:[f118<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=0.0426251 + 2:leaf=-0.0430745 +booster[43]: +0:[f112<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=-0.0315924 + 2:leaf=0.0413181 +booster[44]: +0:[f55<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=-0.037716 + 2:leaf=0.0316046 +booster[45]: +0:[f29<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=0.0384603 + 2:leaf=-0.031591 +booster[46]: +0:[f9<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=-0.0264121 + 2:leaf=0.0318885 +booster[47]: +0:[f39<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=0.0258388 + 2:leaf=-0.0263959 +booster[48]: +0:[f118<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=0.0220629 + 2:leaf=-0.0169775 +booster[49]: +0:[f55<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=-0.0254499 + 2:leaf=0.0207041 +booster[50]: +0:[f126<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=0.022765 + 2:leaf=-0.0334065 +booster[51]: +0:[f21<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=0.022757 + 2:leaf=-0.0227902 +booster[52]: +0:[f29<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=0.0265489 + 2:leaf=-0.0199871 +booster[53]: +0:[f112<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=-0.0149867 + 2:leaf=0.022471 +booster[54]: +0:[f55<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=-0.0175078 + 2:leaf=0.0157137 +booster[55]: +0:[f29<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=0.0182503 + 2:leaf=-0.0143524 +booster[56]: +0:[f112<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=-0.0115217 + 2:leaf=0.0166359 +booster[57]: +0:[f51<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=0.0134613 + 2:leaf=-0.0116378 +booster[58]: +0:[f9<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=-0.00981541 + 2:leaf=0.0115454 +booster[59]: +0:[f55<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=-0.0116732 + 2:leaf=0.00925633 +booster[60]: +0:[f4<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=0.00879889 + 2:leaf=-0.0122642 +booster[61]: +0:[f29<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=0.0105853 + 2:leaf=-0.00918858 +booster[62]: +0:[f112<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=-0.00988643 + 2:leaf=0.0133116 +booster[63]: +0:[f51<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=0.00922858 + 2:leaf=-0.00796718 +booster[64]: +0:[f112<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=-0.00674803 + 2:leaf=0.00923198 +booster[65]: +0:[f29<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=0.00946677 + 2:leaf=-0.00611888 +booster[66]: +0:[f21<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=0.00809434 + 2:leaf=-0.00524561 +booster[67]: +0:[f51<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=0.0058383 + 2:leaf=-0.0047337 +booster[68]: +0:[f9<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=-0.00516364 + 2:leaf=0.00612514 +booster[69]: +0:[f112<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=-0.00393965 + 2:leaf=0.0055112 +booster[70]: +0:[f29<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=0.0062736 + 2:leaf=-0.00406246 +booster[71]: +0:[f39<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=0.00387397 + 2:leaf=-0.00335857 +booster[72]: +0:[f51<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=0.00378672 + 2:leaf=-0.00363264 +booster[73]: +0:[f112<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=-0.00348857 + 2:leaf=0.00454308 +booster[74]: +0:[f51<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=0.00310136 + 2:leaf=-0.00269635 +booster[75]: +0:[f112<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=-0.00232427 + 2:leaf=0.00316355 +booster[76]: +0:[f29<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=0.0033131 + 2:leaf=-0.00214357 +booster[77]: +0:[f9<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=-0.00198535 + 2:leaf=0.00270199 +booster[78]: +0:[f51<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=0.00189522 + 2:leaf=-0.00163941 +booster[79]: +0:[f112<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=-0.0018533 + 2:leaf=0.00251417 +booster[80]: +0:[f29<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=0.00213544 + 2:leaf=-0.00134465 +booster[81]: +0:[f112<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=-0.0010731 + 2:leaf=0.0017787 +booster[82]: +0:[f51<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=0.00170681 + 2:leaf=-0.00144721 +booster[83]: +0:[f112<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=-0.000965197 + 2:leaf=0.00137187 +booster[84]: +0:[f29<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=0.0014236 + 2:leaf=-0.000908222 +booster[85]: +0:[f9<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=-0.000799637 + 2:leaf=0.00110198 +booster[86]: +0:[f51<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=0.000950752 + 2:leaf=-0.000839873 +booster[87]: +0:[f112<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=-0.000841428 + 2:leaf=0.0011364 +booster[88]: +0:[f29<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=0.000900093 + 2:leaf=-0.00055321 +booster[89]: +0:[f112<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=-0.000479465 + 2:leaf=0.000775463 +booster[90]: +0:[f51<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=0.000824745 + 2:leaf=-0.000703525 +booster[91]: +0:[f112<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=-0.000446206 + 2:leaf=0.000627391 +booster[92]: +0:[f51<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=0.000531432 + 2:leaf=-0.000464763 +booster[93]: +0:[f39<-9.53674e-07] yes=1,no=2,missing=1 + 1:leaf=0.000457717 + 2:leaf=-0.000483533 +booster[94]: +0:leaf=-8.69481e-06 +booster[95]: +0:leaf=-2.22842e-06 +booster[96]: +0:leaf=-7.41984e-07 +booster[97]: +0:leaf=6.03395e-07 +booster[98]: +0:leaf=-2.45552e-08 +booster[99]: +0:leaf=-2.45552e-08 +booster[100]: +0:leaf=-2.45552e-08 +booster[101]: +0:leaf=-2.45552e-08 +booster[102]: +0:leaf=-2.45552e-08 +booster[103]: +0:leaf=-2.45552e-08 +booster[104]: +0:leaf=-2.45552e-08 +booster[105]: +0:leaf=-2.45552e-08 +booster[106]: +0:leaf=-2.45552e-08 +booster[107]: +0:leaf=-2.45552e-08 +booster[108]: +0:leaf=-2.45552e-08 +booster[109]: +0:leaf=-2.45552e-08 +booster[110]: +0:leaf=-2.45552e-08 +booster[111]: +0:leaf=-2.45552e-08 +booster[112]: +0:leaf=-2.45552e-08 +booster[113]: +0:leaf=-2.45552e-08 +booster[114]: +0:leaf=-2.45552e-08 +booster[115]: +0:leaf=-2.45552e-08 +booster[116]: +0:leaf=-2.45552e-08 +booster[117]: +0:leaf=-2.45552e-08 +booster[118]: +0:leaf=-2.45552e-08 +booster[119]: +0:leaf=-2.45552e-08 +booster[120]: +0:leaf=-2.45552e-08 +booster[121]: +0:leaf=-2.45552e-08 +booster[122]: +0:leaf=-2.45552e-08 +booster[123]: +0:leaf=-2.45552e-08 +booster[124]: +0:leaf=-2.45552e-08 +booster[125]: +0:leaf=-2.45552e-08 +booster[126]: +0:leaf=-2.45552e-08 +booster[127]: +0:leaf=-2.45552e-08 +booster[128]: +0:leaf=-2.45552e-08 +booster[129]: +0:leaf=-2.45552e-08 +booster[130]: +0:leaf=-2.45552e-08 +booster[131]: +0:leaf=-2.45552e-08 +booster[132]: +0:leaf=-2.45552e-08 +booster[133]: +0:leaf=-2.45552e-08 +booster[134]: +0:leaf=-2.45552e-08 +booster[135]: +0:leaf=-2.45552e-08 +booster[136]: +0:leaf=-2.45552e-08 +booster[137]: +0:leaf=-2.45552e-08 +booster[138]: +0:leaf=-2.45552e-08 +booster[139]: +0:leaf=-2.45552e-08 +booster[140]: +0:leaf=-2.45552e-08 +booster[141]: +0:leaf=-2.45552e-08 +booster[142]: +0:leaf=-2.45552e-08 +booster[143]: +0:leaf=-2.45552e-08 +booster[144]: +0:leaf=-2.45552e-08 +booster[145]: +0:leaf=-2.45552e-08 +booster[146]: +0:leaf=-2.45552e-08 +booster[147]: +0:leaf=-2.45552e-08 +booster[148]: +0:leaf=-2.45552e-08 +booster[149]: +0:leaf=-2.45552e-08 +booster[150]: +0:leaf=-2.45552e-08 +booster[151]: +0:leaf=-2.45552e-08 +booster[152]: +0:leaf=-2.45552e-08 +booster[153]: +0:leaf=-2.45552e-08 +booster[154]: +0:leaf=-2.45552e-08 +booster[155]: +0:leaf=-2.45552e-08 +booster[156]: +0:leaf=-2.45552e-08 +booster[157]: +0:leaf=-2.45552e-08 +booster[158]: +0:leaf=-2.45552e-08 +booster[159]: +0:leaf=-2.45552e-08 +booster[160]: +0:leaf=-2.45552e-08 +booster[161]: +0:leaf=-2.45552e-08 +booster[162]: +0:leaf=-2.45552e-08 +booster[163]: +0:leaf=-2.45552e-08 +booster[164]: +0:leaf=-2.45552e-08 +booster[165]: +0:leaf=-2.45552e-08 +booster[166]: +0:leaf=-2.45552e-08 +booster[167]: +0:leaf=-2.45552e-08 +booster[168]: +0:leaf=-2.45552e-08 +booster[169]: +0:leaf=-2.45552e-08 +booster[170]: +0:leaf=-2.45552e-08 +booster[171]: +0:leaf=-2.45552e-08 +booster[172]: +0:leaf=-2.45552e-08 +booster[173]: +0:leaf=-2.45552e-08 +booster[174]: +0:leaf=-2.45552e-08 +booster[175]: +0:leaf=-2.45552e-08 +booster[176]: +0:leaf=-2.45552e-08 +booster[177]: +0:leaf=-2.45552e-08 +booster[178]: +0:leaf=-2.45552e-08 +booster[179]: +0:leaf=-2.45552e-08 +booster[180]: +0:leaf=-2.45552e-08 +booster[181]: +0:leaf=-2.45552e-08 +booster[182]: +0:leaf=-2.45552e-08 +booster[183]: +0:leaf=-2.45552e-08 +booster[184]: +0:leaf=-2.45552e-08 +booster[185]: +0:leaf=-2.45552e-08 +booster[186]: +0:leaf=-2.45552e-08 +booster[187]: +0:leaf=-2.45552e-08 +booster[188]: +0:leaf=-2.45552e-08 +booster[189]: +0:leaf=-2.45552e-08 +booster[190]: +0:leaf=-2.45552e-08 +booster[191]: +0:leaf=-2.45552e-08 +booster[192]: +0:leaf=-2.45552e-08 +booster[193]: +0:leaf=-2.45552e-08 +booster[194]: +0:leaf=-2.45552e-08 +booster[195]: +0:leaf=-2.45552e-08 +booster[196]: +0:leaf=-2.45552e-08 +booster[197]: +0:leaf=-2.45552e-08 +booster[198]: +0:leaf=-2.45552e-08 +booster[199]: +0:leaf=-2.45552e-08 \ No newline at end of file
