public IntTensor Abs(bool inline = false) { IntTensor result = factory.Create(this.shape); if (dataOnGpu) { result.Gpu(shader); if (inline) { AbsGPU_(); return(this); } else { return(AbsGPU(result)); } } if (inline) { this.Data = data.AsParallel().Select(x => Math.Abs(x)).ToArray(); return(this); } else { result.Data = data.AsParallel().Select(x => Math.Abs(x)).ToArray(); return(result); } }
public IntTensor Add(IntTensor x, bool inline = false) { IntTensor result = factory.Create(this.shape); if (dataOnGpu) { // move result tensor to GPU - TODO: init on gpu instead result.Gpu(shader); // find kernel - TOOD: find all kernels in factory int kernel_id = shader.FindKernel("AddElemInt"); // set function parameters for kernel shader.SetBuffer(kernel_id, "AddElemIntDataA", this.DataBuffer); shader.SetBuffer(kernel_id, "AddElemIntDataB", x.DataBuffer); shader.SetBuffer(kernel_id, "AddElemIntDataResult", result.DataBuffer); // execute kernel shader.Dispatch(kernel_id, this.size, 1, 1); // return result return(result); } result.Data = data.AsParallel().Zip(x.Data.AsParallel(), (a, b) => a + b).ToArray(); return(result); }
public IntTensor Eq(IntTensor other, bool inline = false) { // Run argument checks on CPU // Assuming broadcasting is not supported if (!this.shape.SequenceEqual(other.shape)) { throw new ArgumentException("Tensor dimensions must match"); } if (other == null) { throw new ArgumentNullException(); } if (dataOnGpu) { throw new NotImplementedException(); } else { if (inline) { this.Data = data.AsParallel().Zip(other.Data.AsParallel(), (a, b) => a == b ? 1 : 0).ToArray(); return(this); } else { IntTensor result = factory.Create(this.shape); result.Data = data.AsParallel().Zip(other.Data.AsParallel(), (a, b) => a == b ? 1 : 0).ToArray(); return(result); } } }
public IntTensor Add(IntTensor x, bool inline = false) { IntTensor result = factory.Create(this.shape); if (dataOnGpu) { result.Gpu(shader); if (inline) { AddElemGPU_(x); return(this); } else { return(AddElemGPU(x, result)); } } else { // run Addition on the CPU if (inline) { Data = data.AsParallel().Zip(x.Data.AsParallel(), (a, b) => a + b).ToArray(); return(this); } else { result.Data = data.AsParallel().Zip(x.Data.AsParallel(), (a, b) => a + b).ToArray(); return(result); } } }
public IntTensor UnfoldGPU(int[] new_shape, int size, int dimSize, int sizeBeforeDim, int sizeAfterDim, int step) { IntTensor result = factory.Create(new_shape); result.Gpu(shader); int kernel_id = shader.FindKernel("UnfoldInt"); var sizeBuffer = SendIntToGpu(kernel_id, size, "UnfoldIntSize"); var dimSizeBuffer = SendIntToGpu(kernel_id, dimSize, "UnfoldIntDimSize"); var sizeBeforeDimBuffer = SendIntToGpu(kernel_id, sizeBeforeDim, "UnfoldIntSizeBeforeDim"); var sizeAfterDimBuffer = SendIntToGpu(kernel_id, sizeAfterDim, "UnfoldIntSizeAfterDim"); var stepBuffer = SendIntToGpu(kernel_id, step, "UnfoldIntStep"); shader.SetBuffer(kernel_id, "UnfoldIntData", this.DataBuffer); shader.SetBuffer(kernel_id, "UnfoldIntResult", result.DataBuffer); shader.Dispatch(kernel_id, result.size, 1, 1); sizeBuffer.Release(); dimSizeBuffer.Release(); sizeBeforeDimBuffer.Release(); sizeAfterDimBuffer.Release(); stepBuffer.Release(); return(result); }
public IntTensor Sub(IntTensor x, bool inline = false) { IntTensor result = factory.Create(this.shape); if (dataOnGpu) { result.Gpu(shader); if (inline) { SubGPU_(x); return(this); } else { return(SubGPU(x, result)); } } else { result = inline ? this : factory.Create(this.shape); // run Subtraction on the CPU result.Data = data.AsParallel().Zip(x.Data.AsParallel(), (a, b) => a - b).ToArray(); return(result); } }
public IntTensor Reciprocal(bool inline = false) { IntTensor result = factory.Create(this.shape); if (dataOnGpu) { if (inline) { int kernel_id = shader.FindKernel("ReciprocalInt_"); shader.SetBuffer(kernel_id, "ReciprocalIntData_", this.DataBuffer); shader.Dispatch(kernel_id, this.size, 1, 1); return(this); } else { result.Gpu(shader); int kernel_id = shader.FindKernel("ReciprocalInt"); shader.SetBuffer(kernel_id, "ReciprocalIntData", this.DataBuffer); shader.SetBuffer(kernel_id, "ReciprocalIntDataResult", result.DataBuffer); shader.Dispatch(kernel_id, this.size, 1, 1); return(result); } } if (inline) { this.Data = data.AsParallel().Select(x => (int)(1 / x)).ToArray(); return(this); } result.Data = data.AsParallel().Select(x => (int)(1 / x)).ToArray(); return(result); }
public IntTensor Max(IntTensor other, bool inline = false) { // Run argument checks on CPU anyway just to make sure if (!this.shape.SequenceEqual(other.shape)) { throw new ArgumentException("Tensor dimensions must match"); } if (other == null) { throw new ArgumentNullException(); } if (dataOnGpu) { throw new NotImplementedException(); } else { if (inline) { this.Data = data.AsParallel().Zip(other.Data.AsParallel(), (a, b) => (int)Math.Max(a, b)).ToArray(); return(this); } else { IntTensor result = factory.Create(this.shape); result.Data = data.AsParallel().Zip(other.Data.AsParallel(), (a, b) => (int)Math.Max(a, b)).ToArray(); return(result); } } }
public IntTensor Pow(int value, bool inline = false, IntTensor result = null) { result = inline ? this : factory.Create(this.shape); result.Data = data.AsParallel().Select(x => (int)Math.Pow(x, value)).ToArray(); return(result); }
public bool Equal(IntTensor x, bool inline = false) { if (dataOnGpu) { throw new NotImplementedException(); } return(this.Shape.SequenceEqual(x.Shape) && data.AsParallel().SequenceEqual(x.Data.AsParallel())); }
public IntTensor ReciprocalGPU(IntTensor result) { int kernel_id = shader.FindKernel("ReciprocalInt"); shader.SetBuffer(kernel_id, "ReciprocalIntData", this.DataBuffer); shader.SetBuffer(kernel_id, "ReciprocalIntDataResult", result.DataBuffer); shader.Dispatch(kernel_id, this.size, 1, 1); return(result); }
public void AddElemGPU_(IntTensor tensor) { int kernel_id = shader.FindKernel("AddElemInt_"); shader.SetBuffer(kernel_id, "AddElemIntDataA_", this.DataBuffer); shader.SetBuffer(kernel_id, "AddElemIntDataB_", tensor.DataBuffer); shader.Dispatch(kernel_id, this.size, 1, 1); }
public IntTensor NegGPU(IntTensor result) { int kernel_id = shader.FindKernel("NegateInt"); shader.SetBuffer(kernel_id, "NegateIntData", this.DataBuffer); shader.SetBuffer(kernel_id, "NegateIntResult", result.DataBuffer); shader.Dispatch(kernel_id, this.size, 1, 1); return(result); }
public IntTensor Tan(bool inline = false) { if (dataOnGpu) { throw new NotImplementedException(); } IntTensor result = factory.Create(this.shape); result.Data = data.AsParallel().Select(x => (int)Math.Tan((int)x)).ToArray(); return(result); }
public IntTensor Abs() { if (dataOnGpu) { throw new NotImplementedException(); } IntTensor result = factory.Create(this.shape); result.Data = data.AsParallel().Select(x => Math.Abs(x)).ToArray(); return(result); }
public IntTensor AddElemGPU(IntTensor tensor, IntTensor result) { int kernel_id = shader.FindKernel("AddElemInt"); shader.SetBuffer(kernel_id, "AddElemIntDataA", this.DataBuffer); shader.SetBuffer(kernel_id, "AddElemIntDataB", tensor.DataBuffer); shader.SetBuffer(kernel_id, "AddElemIntDataResult", result.DataBuffer); shader.Dispatch(kernel_id, this.size, 1, 1); return(result); }
public IntTensor Add(IntTensor x, bool inline = false) { if (dataOnGpu) { throw new NotImplementedException(); } IntTensor result = factory.Create(this.shape); result.Data = data.AsParallel().Zip(x.Data.AsParallel(), (a, b) => a + b).ToArray(); return(result); }
public IntTensor Sqrt(bool inline = false) { if (dataOnGpu) { return(this); } IntTensor result = factory.Create(this.shape); result.Data = data.AsParallel().Select(x => (int)Math.Sqrt(x)).ToArray(); return(result); }
public IntTensor Exp(bool inline = false) { if (dataOnGpu) { throw new NotImplementedException(); } IntTensor result = factory.Create(this.shape); result.Data = data.AsParallel().Select(x => handleOverFlow(x)).ToArray(); return(result); }
public IntTensor Sub(int value, bool inline = false) { if (dataOnGpu) { throw new NotImplementedException(); } IntTensor result = inline ? this : factory.Create(this.shape); result.Data = data.AsParallel().Select(x => x - value).ToArray(); return(result); }
public IntTensor Sign(bool inline = false) { IntTensor result = factory.Create(this.shape); if (dataOnGpu) { throw new NotImplementedException(); } if (!inline) { result.Data = data.AsParallel().Select(x => (int)Math.Abs(x) / x).ToArray(); } return(result); }
public IntTensor Pow(IntTensor x, bool inline = false, IntTensor result = null) { if (!IsContiguous() || !x.IsContiguous()) { throw new InvalidOperationException("All tensors must be contiguous, call Contiguous() to convert"); } result = inline ? this : factory.Create(this.shape); result.Data = data.AsParallel().Zip( x.Data.AsParallel(), (a, b) => (int)Math.Pow((int)a, b) ).ToArray(); return(result); }
public IntTensor Add(IntTensor x, bool inline = false) { IntTensor result; if (dataOnGpu) { if (!inline) { result = factory.Create(this.shape); result.Gpu(shader); int kernel_id = shader.FindKernel("AddElemInt"); shader.SetBuffer(kernel_id, "AddElemIntDataA", this.DataBuffer); shader.SetBuffer(kernel_id, "AddElemIntDataB", x.DataBuffer); shader.SetBuffer(kernel_id, "AddElemIntDataResult", result.DataBuffer); shader.Dispatch(kernel_id, this.size, 1, 1); return(result); } else { result = this; int kernel_id = shader.FindKernel("AddElemInt_"); shader.SetBuffer(kernel_id, "AddElemIntDataA_", this.DataBuffer); shader.SetBuffer(kernel_id, "AddElemIntDataB_", x.DataBuffer); shader.Dispatch(kernel_id, this.size, 1, 1); return(result); } } else { result = factory.Create(this.shape); // run Addition on the CPU result.Data = data.AsParallel().Zip(x.Data.AsParallel(), (a, b) => a + b).ToArray(); return(result); } }
public IntTensor Transpose(int dimension1, int dimension2, IntTensor result = null, bool inline = false) { if (!IsContiguous()) { throw new InvalidOperationException("Tensor must be contiguous, call Contiguous() to convert"); } if (dimension1 < 0 || dimension1 >= shape.Length) { throw new ArgumentOutOfRangeException("dimension1"); } if (dimension2 < 0 || dimension2 >= shape.Length) { throw new ArgumentOutOfRangeException("dimension2"); } if (dimension1 == dimension2) { return(this); } var newShape = (int[])shape.Clone(); var tmpDimension = newShape[dimension1]; newShape[dimension1] = newShape[dimension2]; newShape[dimension2] = tmpDimension; result = factory.Create(newShape); var nCpu = SystemInfo.processorCount; Parallel.For(0, nCpu, workerId => { var max = size * (workerId + 1) / nCpu; for (var i = size * workerId / nCpu; i < max; i++) { var idxs = GetIndices(i); var tmp = idxs[dimension1]; idxs[dimension1] = idxs[dimension2]; idxs[dimension2] = tmp; result[idxs] = this[i]; } }); return(result); }
public IntTensor View(int[] new_shape, bool inline = true) { if (!IsContiguous()) { throw new InvalidOperationException("Tensor must be contiguous, call Contiguous() to convert"); } // suppport for -1 parameter value in new_shape var index = Array.IndexOf(new_shape, -1); if (index != -1) { int tempSize = 1; foreach (var s in new_shape) { if (s != -1) { tempSize *= s; } } new_shape[index] = size / tempSize; } if (inline == true) { this.Shape = new_shape; if (dataOnGpu) { shapeBuffer.Release(); shapeBuffer = new ComputeBuffer(shape.Length, sizeof(int)); shapeBuffer.SetData(shape); } setStridesAndCheckShape(); return(this); } else { IntTensor result = factory.Create(new_shape); result.Add(this, inline: true); return(result); } }
public IntTensor Neg(bool inline = false, IntTensor result = null) { if (dataOnGpu) { if (!inline) { result = factory.Create(this.shape); result.Gpu(shader); int kernel_id = shader.FindKernel("NegateInt"); shader.SetBuffer(kernel_id, "NegateIntData", this.DataBuffer); shader.SetBuffer(kernel_id, "NegateIntResult", result.DataBuffer); shader.Dispatch(kernel_id, this.size, 1, 1); return(result); } else { result = this; int kernel_id = shader.FindKernel("NegateInt_"); shader.SetBuffer(kernel_id, "NegateIntData_", result.DataBuffer); shader.Dispatch(kernel_id, this.size, 1, 1); return(result); } } result = this; if (!inline) { result = factory.Create(this.shape); } result.Data = data.AsParallel().Select(x => - x).ToArray(); return(result); }
public IntTensor Neg(bool inline = false, IntTensor result = null) { if (dataOnGpu) { result.Gpu(shader); if (inline) { NegGPU_(); return(this); } else { result = factory.Create(this.shape); return(NegGPU(result)); } } result = this; if (!inline) { result = factory.Create(this.shape); } result.Data = data.AsParallel().Select(x => - x).ToArray(); return(result); }
public IntTensor Reciprocal(bool inline = false) { IntTensor result = factory.Create(this.shape); if (dataOnGpu) { result.Gpu(shader); if (inline) { ReciprocalGPU_(); return(this); } else { return(ReciprocalGPU(result)); } } if (inline) { this.Data = data.AsParallel().Select(x => (int)(1 / x)).ToArray(); return(this); } result.Data = data.AsParallel().Select(x => (int)(1 / x)).ToArray(); return(result); }
public IntTensor TopK(int k, int dim = -1, bool largest = true, bool sorted = true, bool inline = false) { if (dataOnGpu) { throw new NotImplementedException(); } if (dim < 0) { //e.g 5 + (-1) = 4 dim = this.shape.Length + dim; } // check if dim and k match the tensor shape if (dim >= this.shape.Length) { throw new ArgumentException("dimension out of range"); } else if (k == this.shape[dim]) { if (inline) { throw new NotImplementedException(); } if (sorted) { IntTensor tempResult = factory.Create(this.shape, data); /** * TODO sort based on dimension * Example. shape 2x2 * data = [[3,7],[4,2]] * # Exacted behaviour as pytorch # if dim = 0: # result = [[4,2],[3,7]] # if dim = 1: # result = [[3,7],[2,4]] # # Actual # if dim = 0: # result = [[2,3],[4,7]] # if dim = 1: # result = [[2,3],[4,7]] # **/ tempResult.Sort(); return(tempResult); } } else if (k > this.shape[dim]) { throw new ArgumentException("k not in range for dimension"); } // find the top k and saved them in output variable int[] new_shape = (int[])this.shape.Clone(); new_shape[dim] = k; IntTensor result = factory.Create(new_shape); int[] dim_indices = new int[this.strides.Length]; /*** * Example of minMax output * // shape 2x3x3 * tensor = {{{1,2,3},{4,5,6},{7,8,9}},{{10,11,12},{13,14,15},{16,17,18}} } * dim = 1 * k = 2 * // The new shape returnd = 2x2x3 * minMax = { * '00' , {7, 4}, * '01' , {8, 5}, * '02' , {9, 6} , * '10' , {16, 13}, * '11' , {17, 14}, * '12' , {18, 15} * } */ // minMax hold either min or max value depeneds on `largest` value, e.g. if largest == true then remove min values var minMax = new Dictionary <String, List <int> >(); for (int i = 0; i < this.data.Length; i++) { // minMaxKey will be empyt for one dimensional array var minMaxKey = ""; // get the this data array dimension indice for one or more dimensional array this.DataIndex2DimIndices(i, ref dim_indices); for (int d = 0; d < dim_indices.Length; d++) { if (d != dim) { minMaxKey += dim_indices[d].ToString(); } } var minMaxValue = new List <int>() { this.data[this.DimIndices2DataIndex(ref dim_indices)] }; if (dim_indices[dim] <= result.shape[dim] - 1) { if (!minMax.ContainsKey(minMaxKey)) { minMax.Add(minMaxKey, minMaxValue); } else { minMax[minMaxKey].Add(minMaxValue[0]); } } else { if (!minMax.ContainsKey(minMaxKey)) { minMax.Add(minMaxKey, minMaxValue); } else { var list = minMax[minMaxKey]; if (largest) { var listMin = list.Min(); if (listMin < minMaxValue[0]) { list[list.IndexOf(listMin)] = minMaxValue[0]; } } else { var listMax = list.Max(); if (listMax > minMaxValue[0]) { list[list.IndexOf(listMax)] = minMaxValue[0]; } } } } } // convert mimMax to result.Data foreach (var pair in minMax) { for (var d = 0; d < pair.Value.Count; d++) { // complete the key (e.g. pair.Key = '01', key = '010' where dim = 2, d= 0) var key = pair.Key.Insert(dim, d.ToString()); // convert string to array dim_indices = key.Select(n => (int)Char.GetNumericValue(n)).ToArray(); // set value result.Data[result.DimIndices2DataIndex(ref dim_indices)] = pair.Value[d]; } } if (sorted) { /** * TODO sort based on dimension * Example. shape 2x2 * data = [[3,7],[4,2]] * # Exacted behaviour as pytorch # if dim = 0: # result = [[4,2],[3,7]] # if dim = 1: # result = [[3,7],[2,4]] # # Actual # if dim = 0: # result = [[2,3],[4,7]] # if dim = 1: # result = [[2,3],[4,7]] # **/ result.Sort(); } if (inline) { throw new NotImplementedException(); } else { return(result); } }
public IntTensor Unfold(int dim, int size, int step, bool inline = false) { // Getting the number of new tensors to add int new_dim_size = Mathf.CeilToInt((this.shape [dim] - size + 1) / (float)step); // Declaring required variables int[] new_shape = new int[this.shape.Count() + 1]; long newTensorSize = 1; int dimSize = this.shape[dim]; int sizeBeforeDim = 1; int sizeAfterDim = 1; for (int i = 0; i < new_shape.Count(); i++) { if (i == 0) { new_shape[i] = new_dim_size; } else if ((i - 1) == dim) { new_shape[i] = size; } else { new_shape[i] = this.shape[i - 1]; } if ((i != 0) && ((i - 1) < dim)) { sizeBeforeDim *= new_shape[i]; } if ((i - 1) > dim) { sizeAfterDim *= new_shape[i]; } newTensorSize *= new_shape[i]; } if (dataOnGpu) { throw new NotImplementedException(); } else { if (inline) { throw new NotImplementedException(); } else { IntTensor result = factory.Create(new_shape); Parallel.For(0, newTensorSize, index => { // Calculating the offset due to step int currentStep = (int)(index / (sizeBeforeDim * size * sizeAfterDim)); int updatedIndex = (int)(index % (sizeBeforeDim * size * sizeAfterDim)); int stepOffset = currentStep * sizeAfterDim * step; // Calculating the offset due to size difference of dim int sizeIndex = (int)(updatedIndex / (size * sizeAfterDim)); int sizeOffset = sizeIndex * (dimSize - size) * sizeAfterDim; int indexToQuery = updatedIndex + stepOffset + sizeOffset; result.data[index] = data[indexToQuery]; }); return(result); } } }