Пример #1
0
        /// <summary>
        /// Constructs a potentially multi-dimensional vector type.
        /// </summary>
        /// <param name="itemType">The type of the items contained in the vector.</param>
        /// <param name="dimensions">The dimensions. Note that, like <see cref="Dimensions"/>, must be non-empty, with all
        /// non-negative values. Also, because <see cref="Size"/> is the product of <see cref="Dimensions"/>, the result of
        /// multiplying all these values together must not overflow <see cref="int"/>.</param>
        public VectorDataViewType(PrimitiveDataViewType itemType, ImmutableArray <int> dimensions)
            : base(GetRawType(itemType))
        {
            Contracts.CheckParam(dimensions.Length > 0, nameof(dimensions));
            Contracts.CheckParam(dimensions.All(d => d >= 0), nameof(dimensions));

            ItemType   = itemType;
            Dimensions = dimensions;
            Size       = ComputeSize(Dimensions);
        }
Пример #2
0
        /// <summary>
        /// Constructs a potentially multi-dimensional vector type.
        /// </summary>
        /// <param name="itemType">The type of the items contained in the vector.</param>
        /// <param name="dimensions">The dimensions. Note that, like <see cref="Dimensions"/>, must be non-empty, with all
        /// non-negative values. Also, because <see cref="Size"/> is the product of <see cref="Dimensions"/>, the result of
        /// multiplying all these values together must not overflow <see cref="int"/>.</param>
        public VectorDataViewType(PrimitiveDataViewType itemType, params int[] dimensions)
            : base(GetRawType(itemType))
        {
            Contracts.CheckParam(ArrayUtils.Size(dimensions) > 0, nameof(dimensions));
            Contracts.CheckParam(dimensions.All(d => d >= 0), nameof(dimensions));

            ItemType   = itemType;
            Dimensions = dimensions.ToImmutableArray();
            Size       = ComputeSize(Dimensions);
        }
Пример #3
0
        internal VectorType(PrimitiveDataViewType itemType, VectorType template, params int[] dims)
            : base(GetRawType(itemType))
        {
            Contracts.CheckValue(template, nameof(template));
            Contracts.CheckParam(Utils.Size(dims) > 0, nameof(dims));
            Contracts.CheckParam(dims.All(d => d >= 0), nameof(dims));

            ItemType   = itemType;
            Dimensions = template.Dimensions.AddRange(dims);
            Size       = ComputeSize(Dimensions);
        }
Пример #4
0
        internal static ValueGetter <VBuffer <TDst> > GetVecGetterAs <TDst>(PrimitiveDataViewType typeDst, SlotCursor cursor)
        {
            Contracts.CheckValue(typeDst, nameof(typeDst));
            Contracts.CheckParam(typeDst.RawType == typeof(TDst), nameof(typeDst));

            var typeSrc = cursor.GetSlotType();

            Func <VectorType, PrimitiveDataViewType, GetterFactory, ValueGetter <VBuffer <TDst> > > del = GetVecGetterAsCore <int, TDst>;
            var methodInfo = del.GetMethodInfo().GetGenericMethodDefinition().MakeGenericMethod(typeSrc.ItemType.RawType, typeof(TDst));

            return((ValueGetter <VBuffer <TDst> >)methodInfo.Invoke(null, new object[] { typeSrc, typeDst, GetterFactory.Create(cursor) }));
        }
Пример #5
0
            public static ColInfo Create(string name, PrimitiveDataViewType itemType, Segment[] segs, bool user)
            {
                Contracts.AssertNonEmpty(name);
                Contracts.AssertValue(itemType);
                Contracts.AssertValueOrNull(segs);

                int          size = 0;
                DataViewType type = itemType;

                if (segs != null)
                {
                    var order = Utils.GetIdentityPermutation(segs.Length);

                    if ((segs.Length != 0) && (segs[0].Name is null))
                    {
                        Array.Sort(order, (x, y) => segs[x].Min.CompareTo(segs[y].Min));

                        // Check that the segments are disjoint.
                        for (int i = 1; i < order.Length; i++)
                        {
                            int a = order[i - 1];
                            int b = order[i];
                            Contracts.Assert(segs[a].Min <= segs[b].Min);
                            if (segs[a].Lim > segs[b].Min)
                            {
                                throw user?
                                      Contracts.ExceptUserArg(nameof(Column.Source), "Intervals specified for column '{0}' overlap", name) :
                                          Contracts.ExceptDecode("Intervals specified for column '{0}' overlap", name);
                            }
                        }
                    }

                    // Note: since we know that the segments don't overlap, we're guaranteed that
                    // the sum of their sizes doesn't overflow.
                    for (int i = 0; i < segs.Length; i++)
                    {
                        var seg = segs[i];
                        size += (seg.Name is null) ? seg.Lim - seg.Min : 1;
                    }
                    Contracts.Assert(size >= segs.Length);

                    if (size > 1 || segs[0].ForceVector)
                    {
                        type = new VectorDataViewType(itemType, size);
                    }
                }
                else
                {
                    size++;
                }

                return(new ColInfo(name, type, segs, size));
            }
Пример #6
0
        /// <summary>
        /// Tries to get the annotation kind of the specified type for a column.
        /// </summary>
        /// <typeparam name="T">The raw type of the annotation, should match the PrimitiveType type</typeparam>
        /// <param name="schema">The schema</param>
        /// <param name="type">The type of the annotation</param>
        /// <param name="kind">The annotation kind</param>
        /// <param name="col">The column</param>
        /// <param name="value">The value to return, if successful</param>
        /// <returns>True if the annotation of the right type exists, false otherwise</returns>
        public static bool TryGetAnnotation <T>(this DataViewSchema schema, PrimitiveDataViewType type, string kind, int col, ref T value)
        {
            Contracts.CheckValue(schema, nameof(schema));
            Contracts.CheckValue(type, nameof(type));

            var annotationType = schema[col].Annotations.Schema.GetColumnOrNull(kind)?.Type;

            if (!type.Equals(annotationType))
            {
                return(false);
            }
            schema[col].Annotations.GetValue(kind, ref value);
            return(true);
        }
Пример #7
0
        /// <summary>
        /// Given the item type, typeDst, a row, and column index, return a ValueGetter for the vector-valued
        /// column with a conversion to a vector of typeDst, if needed. This is the weakly typed version of
        /// <see cref="GetVecGetterAs{TDst}(PrimitiveDataViewType, DataViewRow, int)"/>.
        /// </summary>
        public static Delegate GetVecGetterAs(PrimitiveDataViewType typeDst, DataViewRow row, int col)
        {
            Contracts.CheckValue(typeDst, nameof(typeDst));
            Contracts.CheckValue(row, nameof(row));
            Contracts.CheckParam(0 <= col && col < row.Schema.Count, nameof(col));
            Contracts.CheckParam(row.IsColumnActive(col), nameof(col), "column was not active");

            var typeSrc = row.Schema[col].Type as VectorType;

            Contracts.Check(typeSrc != null, "Source column type must be vector");

            Func <VectorType, PrimitiveDataViewType, GetterFactory, ValueGetter <VBuffer <int> > > del = GetVecGetterAsCore <int, int>;
            var methodInfo = del.GetMethodInfo().GetGenericMethodDefinition().MakeGenericMethod(typeSrc.ItemType.RawType, typeDst.RawType);

            return((Delegate)methodInfo.Invoke(null, new object[] { typeSrc, typeDst, GetterFactory.Create(row, col) }));
        }
Пример #8
0
        private static ValueGetter <VBuffer <TDst> > GetVecGetterAsCore <TSrc, TDst>(VectorType typeSrc, PrimitiveDataViewType typeDst, GetterFactory getterFact)
        {
            Contracts.Assert(typeof(TSrc) == typeSrc.ItemType.RawType);
            Contracts.Assert(typeof(TDst) == typeDst.RawType);
            Contracts.AssertValue(getterFact);

            var  getter = getterFact.GetGetter <VBuffer <TSrc> >();
            bool identity;
            var  conv = Conversions.Instance.GetStandardConversion <TSrc, TDst>(typeSrc.ItemType, typeDst, out identity);

            if (identity)
            {
                Contracts.Assert(typeof(TSrc) == typeof(TDst));
                return((ValueGetter <VBuffer <TDst> >)(Delegate) getter);
            }

            int size = typeSrc.Size;
            var src  = default(VBuffer <TSrc>);

            return((ref VBuffer <TDst> dst) =>
            {
                getter(ref src);
                if (size > 0)
                {
                    Contracts.Check(src.Length == size);
                }

                var srcValues = src.GetValues();
                int count = srcValues.Length;
                var editor = VBufferEditor.Create(ref dst, src.Length, count);
                if (count > 0)
                {
                    // REVIEW: This would be faster if there were loops for each std conversion.
                    // Consider adding those to the Conversions class.
                    for (int i = 0; i < count; i++)
                    {
                        conv(in srcValues[i], ref editor.Values[i]);
                    }

                    if (!src.IsDense)
                    {
                        var srcIndices = src.GetIndices();
                        srcIndices.CopyTo(editor.Indices);
                    }
                }
                dst = editor.Commit();
            });
        }
 public AssignmentColumn(PrimitiveDataViewType type, T[] values)
     : base(type, values)
 {
 }
 /// <summary>
 /// Adds a VBuffer{T} valued column.
 /// </summary>
 public void AddColumn <T>(string name, ValueGetter <VBuffer <ReadOnlyMemory <char> > > getNames, PrimitiveDataViewType itemType, params VBuffer <T>[] values)
 {
     _host.CheckValue(getNames, nameof(getNames));
     _host.CheckParam(itemType != null && itemType.RawType == typeof(T), nameof(itemType));
     CheckLength(name, values);
     _columns.Add(new VBufferColumn <T>(itemType, values));
     _getSlotNames.Add(name, getNames);
     _names.Add(name);
 }
Пример #11
0
 /// <summary>
 /// Add key values metadata.
 /// </summary>
 /// <typeparam name="TValue">The value type of key values.</typeparam>
 /// <param name="builder">The <see cref="DataViewSchema.Metadata.Builder"/> to which to add the key values.</param>
 /// <param name="size">The size of key values vector.</param>
 /// <param name="valueType">The value type of key values. Its raw type must match <typeparamref name="TValue"/>.</param>
 /// <param name="getter">The getter delegate for the key values.</param>
 public static void AddKeyValues <TValue>(this DataViewSchema.Metadata.Builder builder, int size, PrimitiveDataViewType valueType, ValueGetter <VBuffer <TValue> > getter)
 => builder.Add(MetadataUtils.Kinds.KeyValues, new VectorType(valueType, size), getter);
Пример #12
0
        public static InternalSchemaDefinition Create(Type userType, SchemaDefinition userSchemaDefinition)
        {
            Contracts.AssertValue(userType);
            Contracts.AssertValueOrNull(userSchemaDefinition);

            if (userSchemaDefinition == null)
            {
                userSchemaDefinition = SchemaDefinition.Create(userType);
            }

            Column[] dstCols = new Column[userSchemaDefinition.Count];

            for (int i = 0; i < userSchemaDefinition.Count; ++i)
            {
                var col = userSchemaDefinition[i];
                if (col.MemberName == null)
                {
                    throw Contracts.ExceptParam(nameof(userSchemaDefinition), "Null field name detected in schema definition");
                }

                bool       isVector;
                Type       dataItemType;
                MemberInfo memberInfo = null;

                if (col.Generator == null)
                {
                    memberInfo = userType.GetField(col.MemberName);

                    if (memberInfo == null)
                    {
                        memberInfo = userType.GetProperty(col.MemberName);
                    }

                    if (memberInfo == null)
                    {
                        throw Contracts.ExceptParam(nameof(userSchemaDefinition), "No field or property with name '{0}' found in type '{1}'",
                                                    col.MemberName,
                                                    userType.FullName);
                    }

                    //Clause to handle the field that may be used to expose the cursor channel.
                    //This field does not need a column.
                    if ((memberInfo is FieldInfo && (memberInfo as FieldInfo).FieldType == typeof(IChannel)) ||
                        (memberInfo is PropertyInfo && (memberInfo as PropertyInfo).PropertyType == typeof(IChannel)))
                    {
                        continue;
                    }

                    GetVectorAndItemType(memberInfo, out isVector, out dataItemType);
                }
                else
                {
                    var parameterType = col.ReturnType;
                    if (parameterType == null)
                    {
                        throw Contracts.ExceptParam(nameof(userSchemaDefinition), "No return parameter found in computed column.");
                    }
                    GetVectorAndItemType("returnType", parameterType, null, out isVector, out dataItemType);
                }
                // Infer the column name.
                var colName = string.IsNullOrEmpty(col.ColumnName) ? col.MemberName : col.ColumnName;
                // REVIEW: Because order is defined, we allow duplicate column names, since producing an IDataView
                // with duplicate column names is completely legal. Possible objection is that we should make it less
                // convenient to produce "hidden" columns, since this may not be of practical use to users.

                DataViewType colType;
                if (col.ColumnType == null)
                {
                    // Infer a type as best we can.
                    PrimitiveDataViewType itemType = ColumnTypeExtensions.PrimitiveTypeFromType(dataItemType);
                    colType = isVector ? new VectorDataViewType(itemType) : (DataViewType)itemType;
                }
                else
                {
                    // Make sure that the types are compatible with the declared type, including
                    // whether it is a vector type.
                    VectorDataViewType columnVectorType = col.ColumnType as VectorDataViewType;
                    if (isVector != (columnVectorType != null))
                    {
                        throw Contracts.ExceptParam(nameof(userSchemaDefinition), "Column '{0}' is supposed to be {1}, but type of associated field '{2}' is {3}",
                                                    colName, columnVectorType != null ? "vector" : "scalar", col.MemberName, isVector ? "vector" : "scalar");
                    }
                    DataViewType itemType = columnVectorType?.ItemType ?? col.ColumnType;
                    if (itemType.RawType != dataItemType)
                    {
                        throw Contracts.ExceptParam(nameof(userSchemaDefinition), "Column '{0}' is supposed to have item type {1}, but associated field has type {2}",
                                                    colName, itemType.RawType, dataItemType);
                    }
                    colType = col.ColumnType;
                }

                dstCols[i] = col.Generator != null ?
                             new Column(colName, colType, col.Generator, col.AnnotationInfos)
                    : new Column(colName, colType, memberInfo, col.AnnotationInfos);
            }
            return(new InternalSchemaDefinition(dstCols));
        }
Пример #13
0
 private static Type GetRawType(PrimitiveDataViewType itemType)
 {
     Contracts.CheckValue(itemType, nameof(itemType));
     return(typeof(VBuffer <>).MakeGenericType(itemType.RawType));
 }