コード例 #1
0
 private static void AssignPointerFields(GPGPU gpu, object hostObject, object deviceObject, List <FieldMapping> pointerFields)
 {
     foreach (FieldMapping mapping in pointerFields)
     {
         object fieldValue = mapping.HostObjectField.GetValue(hostObject);
         // Get the IntPtr to the device memory for the array.
         var devicePointer = TryGetDeviceMemoryFromHostObject(gpu, fieldValue);
         if (devicePointer == null)
         {
             throw new ArgumentException("No device memory allocated for field " + mapping.Name);
         }
         // The device object contains this pointer.
         mapping.DeviceObjectField.SetValue(deviceObject, devicePointer.Pointer);
         // If the field is an array then set the dimension fields too.
         if (mapping is ArrayFieldMapping)
         {
             ArrayFieldMapping arrayFieldMapping = (ArrayFieldMapping)mapping;
             Array             array             = fieldValue as Array;
             for (int i = 0; i < arrayFieldMapping.ArrayRank; ++i)
             {
                 arrayFieldMapping.DeviceObjectDimensionFields[i].SetValue(deviceObject, array.GetLength(i));
             }
         }
     }
 }
コード例 #2
0
        /// <summary>
        /// Create type that contains pointers to device arrays.
        /// </summary>
        private static DeviceTypeInfo CreateDeviceType(Type hostType)
        {
            DeviceTypeInfo dummy;

            if (deviceTypeLookup.TryGetValue(hostType, out dummy))
            {
                return(dummy);
            }

            // We are assuming that the device class is standard layout.
            // We further assume that all array fields are actually pointers to device memory.
            // For now assume that anything that is not an array is blittable.

            TypeBuilder tb = moduleBuilder.DefineType("DynamicType" + hostType.Name, TypeAttributes.Public |
                                                      TypeAttributes.Sealed | TypeAttributes.SequentialLayout |
                                                      TypeAttributes.Serializable, typeof(ValueType));

            var fields = GetFieldsStandardLayout(hostType);

            var pointerFields    = new List <FieldMapping>();
            var nonPointerFields = new List <FieldMapping>();

            // Any class (i.e. not value type), which includes arrays, is replaced by an IntPtr
            foreach (var field in fields)
            {
                if (field.FieldType.IsClass)
                {
                    tb.DefineField(field.Name, typeof(IntPtr), FieldAttributes.Public);
                    FieldMapping newPointerFieldMapping;
                    // If this is an array, then we add in int fields to contain the dimensions of the array.
                    if (field.FieldType.IsArray)
                    {
                        newPointerFieldMapping = new ArrayFieldMapping()
                        {
                            Name = field.Name, HostObjectField = field
                        };
                        ((ArrayFieldMapping)newPointerFieldMapping).ArrayRank = field.FieldType.GetArrayRank();
                        for (int r = 0; r < field.FieldType.GetArrayRank(); r++)
                        {
                            string dimensionFieldName = String.Format("{0}Len{1}", field.Name, r);
                            tb.DefineField(dimensionFieldName, typeof(int), FieldAttributes.Public);
                            ((ArrayFieldMapping)newPointerFieldMapping).ArrayDimensionNames.Add(dimensionFieldName);
                        }
                    }
                    else
                    {
                        newPointerFieldMapping = new FieldMapping()
                        {
                            Name = field.Name, HostObjectField = field
                        };
                    }
                    pointerFields.Add(newPointerFieldMapping);
                }
                else
                {
                    tb.DefineField(field.Name, field.FieldType, FieldAttributes.Public);
                    nonPointerFields.Add(new FieldMapping()
                    {
                        Name = field.Name, HostObjectField = field
                    });
                }
            }
            Type newType = tb.CreateType();

            foreach (var pointerField in pointerFields)
            {
                pointerField.DeviceObjectField = newType.GetFields().Where(f => f.Name == pointerField.Name).FirstOrDefault();
                if (pointerField is ArrayFieldMapping)
                {
                    foreach (string dimensionName in ((ArrayFieldMapping)pointerField).ArrayDimensionNames)
                    {
                        ((ArrayFieldMapping)pointerField).DeviceObjectDimensionFields.Add(
                            newType.GetFields().Where(f => f.Name == dimensionName).FirstOrDefault());
                    }
                }
            }
            foreach (var nonPointerField in nonPointerFields)
            {
                nonPointerField.DeviceObjectField = newType.GetFields().Where(f => f.Name == nonPointerField.Name).FirstOrDefault();
            }
            var deviceTypeInfo = new DeviceTypeInfo()
            {
                DeviceType = newType, NonPointerFields = nonPointerFields, PointerFields = pointerFields
            };

            deviceTypeLookup.Add(hostType, deviceTypeInfo);
            return(deviceTypeInfo);
        }