internal DataViewRow GetStatefulRows(DataViewRow input, IRowToRowMapper mapper, IEnumerable <DataViewSchema.Column> activeColumns, List <StatefulRow> rows)
        {
            Contracts.CheckValue(input, nameof(input));
            Contracts.CheckValue(activeColumns, nameof(activeColumns));

            IRowToRowMapper[] innerMappers = new IRowToRowMapper[0];
            if (mapper is CompositeRowToRowMapper compositeMapper)
            {
                innerMappers = compositeMapper.InnerMappers;
            }

            var activeIndices = new HashSet <int>(activeColumns.Select(c => c.Index));

            if (innerMappers.Length == 0)
            {
                bool differentActive = false;
                for (int c = 0; c < input.Schema.Count; ++c)
                {
                    bool wantsActive = activeIndices.Contains(c);
                    bool isActive    = input.IsColumnActive(input.Schema[c]);
                    differentActive |= wantsActive != isActive;

                    if (wantsActive && !isActive)
                    {
                        throw Contracts.ExceptParam(nameof(input), $"Mapper required column '{input.Schema[c].Name}' active but it was not.");
                    }
                }

                var row = mapper.GetRow(input, activeColumns);
                if (row is StatefulRow statefulRow)
                {
                    rows.Add(statefulRow);
                }
                return(row);
            }

            // For each of the inner mappers, we will be calling their GetRow method, but to do so we need to know
            // what we need from them. The last one will just have the input, but the rest will need to be
            // computed based on the dependencies of the next one in the chain.
            var deps = new IEnumerable <DataViewSchema.Column> [innerMappers.Length];

            deps[deps.Length - 1] = activeColumns;
            for (int i = deps.Length - 1; i >= 1; --i)
            {
                deps[i - 1] = innerMappers[i].GetDependencies(deps[i]);
            }

            DataViewRow result = input;

            for (int i = 0; i < innerMappers.Length; ++i)
            {
                result = GetStatefulRows(result, innerMappers[i], deps[i], rows);
                if (result is StatefulRow statefulResult)
                {
                    rows.Add(statefulResult);
                }
            }
            return(result);
        }
예제 #2
0
        internal DataViewRow GetStatefulRows(DataViewRow input, IRowToRowMapper mapper, Func <int, bool> active, List <StatefulRow> rows)
        {
            Contracts.CheckValue(input, nameof(input));
            Contracts.CheckValue(active, nameof(active));

            IRowToRowMapper[] innerMappers = new IRowToRowMapper[0];
            if (mapper is CompositeRowToRowMapper compositeMapper)
            {
                innerMappers = compositeMapper.InnerMappers;
            }

            if (innerMappers.Length == 0)
            {
                bool differentActive = false;
                for (int c = 0; c < input.Schema.Count; ++c)
                {
                    bool wantsActive = active(c);
                    bool isActive    = input.IsColumnActive(c);
                    differentActive |= wantsActive != isActive;

                    if (wantsActive && !isActive)
                    {
                        throw Contracts.ExceptParam(nameof(input), $"Mapper required column '{input.Schema[c].Name}' active but it was not.");
                    }
                }

                var row = mapper.GetRow(input, active);
                if (row is StatefulRow statefulRow)
                {
                    rows.Add(statefulRow);
                }
                return(row);
            }

            // For each of the inner mappers, we will be calling their GetRow method, but to do so we need to know
            // what we need from them. The last one will just have the input, but the rest will need to be
            // computed based on the dependencies of the next one in the chain.
            var deps = new Func <int, bool> [innerMappers.Length];

            deps[deps.Length - 1] = active;
            for (int i = deps.Length - 1; i >= 1; --i)
            {
                var inputCols = innerMappers[i].OutputSchema.Where(c => deps[i](c.Index));
                var cols      = innerMappers[i].GetDependencies(inputCols).ToArray();
                deps[i - 1] = c => cols.Length > 0 ? cols.Any(col => col.Index == c) : false;
            }

            DataViewRow result = input;

            for (int i = 0; i < innerMappers.Length; ++i)
            {
                result = GetStatefulRows(result, innerMappers[i], deps[i], rows);
                if (result is StatefulRow statefulResult)
                {
                    rows.Add(statefulResult);
                }
            }
            return(result);
        }
        private protected virtual void PredictionEngineCore(IHostEnvironment env, DataViewConstructionUtils.InputRow <TSrc> inputRow,
                                                            IRowToRowMapper mapper, bool ignoreMissingColumns, SchemaDefinition outputSchemaDefinition, out Action disposer, out IRowReadableAs <TDst> outputRow)
        {
            var cursorable = TypedCursorable <TDst> .Create(env, new EmptyDataView(env, mapper.OutputSchema), ignoreMissingColumns, outputSchemaDefinition);

            var outputRowLocal = mapper.GetRow(inputRow, mapper.OutputSchema);

            outputRow = cursorable.GetRow(outputRowLocal);
            disposer  = inputRow.Dispose;
        }
        private protected override void PredictionEngineCore(IHostEnvironment env, DataViewConstructionUtils.InputRow <TSrc> inputRow,
                                                             IRowToRowMapper mapper, bool ignoreMissingColumns, SchemaDefinition outputSchemaDefinition, out Action disposer, out IRowReadableAs <TDst> outputRow)
        {
            List <StatefulRow> rows           = new List <StatefulRow>();
            DataViewRow        outputRowLocal = outputRowLocal = GetStatefulRows(inputRow, mapper, mapper.OutputSchema, rows);
            var cursorable = TypedCursorable <TDst> .Create(env, new EmptyDataView(env, mapper.OutputSchema), ignoreMissingColumns, outputSchemaDefinition);

            _pinger   = CreatePinger(rows);
            disposer  = outputRowLocal.Dispose;
            outputRow = cursorable.GetRow(outputRowLocal);
        }
        public IRowToRowMapper GetRowToRowMapper(Schema inputSchema)
        {
            Contracts.CheckValue(inputSchema, nameof(inputSchema));
            Contracts.Check(IsRowToRowMapper, nameof(GetRowToRowMapper) + " method called despite " + nameof(IsRowToRowMapper) + " being false.");

            IRowToRowMapper[] mappers = new IRowToRowMapper[_transformers.Length];
            Schema            schema  = inputSchema;

            for (int i = 0; i < mappers.Length; ++i)
            {
                mappers[i] = _transformers[i].GetRowToRowMapper(schema);
                schema     = mappers[i].OutputSchema;
            }
            return(new CompositeRowToRowMapper(inputSchema, mappers));
        }
        private IRowToRowMapper GetRowToRowMapper(Schema inputSchema)
        {
            Contracts.CheckValue(inputSchema, nameof(inputSchema));
            Contracts.Check(IsRowToRowMapper(InputTransformer), nameof(GetRowToRowMapper) +
                            " method called despite " + nameof(IsRowToRowMapper) + " being false. or transformer not being " + nameof(IStatefulTransformer));

            if (!(InputTransformer is ITransformerChainAccessor))
            {
                if (InputTransformer is IStatefulTransformer)
                {
                    return(((IStatefulTransformer)InputTransformer).GetStatefulRowToRowMapper(inputSchema));
                }
                else
                {
                    return(InputTransformer.GetRowToRowMapper(inputSchema));
                }
            }

            Contracts.Check(InputTransformer is ITransformerChainAccessor);

            var transformers = ((ITransformerChainAccessor )InputTransformer).Transformers;

            IRowToRowMapper[] mappers = new IRowToRowMapper[transformers.Length];
            Schema            schema  = inputSchema;

            for (int i = 0; i < mappers.Length; ++i)
            {
                if (transformers[i] is IStatefulTransformer)
                {
                    mappers[i] = ((IStatefulTransformer)transformers[i]).GetStatefulRowToRowMapper(schema);
                }
                else
                {
                    mappers[i] = transformers[i].GetRowToRowMapper(schema);
                }

                schema = mappers[i].OutputSchema;
            }
            return(new CompositeRowToRowMapper(inputSchema, mappers));
        }
        internal IRow GetStatefulRows(IRow input, IRowToRowMapper mapper, Func <int, bool> active,
                                      List <IStatefulRow> rows, out Action disposer)
        {
            Contracts.CheckValue(input, nameof(input));
            Contracts.CheckValue(active, nameof(active));

            disposer = null;
            IRowToRowMapper[] innerMappers = new IRowToRowMapper[0];
            if (mapper is CompositeRowToRowMapper)
            {
                innerMappers = ((CompositeRowToRowMapper)mapper).InnerMappers;
            }

            if (innerMappers.Length == 0)
            {
                bool differentActive = false;
                for (int c = 0; c < input.Schema.ColumnCount; ++c)
                {
                    bool wantsActive = active(c);
                    bool isActive    = input.IsColumnActive(c);
                    differentActive |= wantsActive != isActive;

                    if (wantsActive && !isActive)
                    {
                        throw Contracts.ExceptParam(nameof(input), $"Mapper required column '{input.Schema.GetColumnName(c)}' active but it was not.");
                    }
                }

                var row = mapper.GetRow(input, active, out disposer);
                if (row is IStatefulRow)
                {
                    rows.Add((IStatefulRow)row);
                }

                return(row);
            }

            // For each of the inner mappers, we will be calling their GetRow method, but to do so we need to know
            // what we need from them. The last one will just have the input, but the rest will need to be
            // computed based on the dependencies of the next one in the chain.
            var deps = new Func <int, bool> [innerMappers.Length];

            deps[deps.Length - 1] = active;
            for (int i = deps.Length - 1; i >= 1; --i)
            {
                deps[i - 1] = innerMappers[i].GetDependencies(deps[i]);
            }

            IRow result = input;

            for (int i = 0; i < innerMappers.Length; ++i)
            {
                Action localDisp;
                result = GetStatefulRows(result, innerMappers[i], deps[i], rows, out localDisp);
                if (result is IStatefulRow)
                {
                    rows.Add((IStatefulRow)result);
                }

                if (localDisp != null)
                {
                    if (disposer == null)
                    {
                        disposer = localDisp;
                    }
                    else
                    {
                        disposer = localDisp + disposer;
                    }
                    // We want the last disposer to be called first, so the order of the addition here is important.
                }
            }

            return(result);
        }
 /// <summary>
 /// Extension method.
 /// </summary>
 /// <param name="rowMapper"></param>
 /// <param name="input"></param>
 /// <param name="activeColumns"></param>
 /// <returns></returns>
 public static DataViewRow GetRow(this IRowToRowMapper rowMapper, DataViewRow input, params DataViewSchema.Column[] activeColumns)
 => rowMapper.GetRow(input, activeColumns);