Allow for uniform initialization in a single step. (#136)

This commit is contained in:
Laurent Mazare
2023-07-11 08:52:29 +01:00
committed by GitHub
parent b31a3bbdcb
commit ae79c00e48
5 changed files with 43 additions and 13 deletions

View File

@ -895,7 +895,7 @@ impl CpuStorage {
MatMul(bmnk).map(self, lhs_l, rhs, rhs_l) MatMul(bmnk).map(self, lhs_l, rhs, rhs_l)
} }
pub(crate) fn rand_uniform(shape: &Shape, dtype: DType) -> Result<Self> { pub(crate) fn rand_uniform(shape: &Shape, dtype: DType, min: f64, max: f64) -> Result<Self> {
use rand::prelude::*; use rand::prelude::*;
let elem_count = shape.elem_count(); let elem_count = shape.elem_count();
@ -907,7 +907,7 @@ impl CpuStorage {
DType::F32 => { DType::F32 => {
let mut data = Vec::new(); let mut data = Vec::new();
data.reserve(elem_count); data.reserve(elem_count);
let uniform = rand::distributions::Uniform::new(0f32, 1f32); let uniform = rand::distributions::Uniform::new(min as f32, max as f32);
for _i in 0..elem_count { for _i in 0..elem_count {
data.push(rng.sample::<f32, _>(uniform)) data.push(rng.sample::<f32, _>(uniform))
} }
@ -916,7 +916,7 @@ impl CpuStorage {
DType::F64 => { DType::F64 => {
let mut data = Vec::new(); let mut data = Vec::new();
data.reserve(elem_count); data.reserve(elem_count);
let uniform = rand::distributions::Uniform::new(0f64, 1f64); let uniform = rand::distributions::Uniform::new(min, max);
for _i in 0..elem_count { for _i in 0..elem_count {
data.push(rng.sample::<f64, _>(uniform)) data.push(rng.sample::<f64, _>(uniform))
} }

View File

@ -153,7 +153,13 @@ impl CudaDevice {
}) })
} }
pub(crate) fn rand_uniform(&self, shape: &Shape, dtype: DType) -> Result<CudaStorage> { pub(crate) fn rand_uniform(
&self,
shape: &Shape,
dtype: DType,
lo: f64,
up: f64,
) -> Result<CudaStorage> {
let elem_count = shape.elem_count(); let elem_count = shape.elem_count();
let curand = self.curand.lock().unwrap(); let curand = self.curand.lock().unwrap();
let slice = match dtype { let slice = match dtype {
@ -174,6 +180,10 @@ impl CudaDevice {
CudaStorageSlice::F64(data) CudaStorageSlice::F64(data)
} }
}; };
if lo != 0.0 || up != 1.0 {
let layout = Layout::contiguous(shape);
Affine(up - lo, lo).map(&slice, self, &layout)?;
}
Ok(CudaStorage { Ok(CudaStorage {
slice, slice,
device: self.clone(), device: self.clone(),

View File

@ -109,14 +109,20 @@ impl Device {
} }
} }
pub(crate) fn rand_uniform(&self, shape: &Shape, dtype: DType) -> Result<Storage> { pub(crate) fn rand_uniform(
&self,
shape: &Shape,
dtype: DType,
lo: f64,
up: f64,
) -> Result<Storage> {
match self { match self {
Device::Cpu => { Device::Cpu => {
let storage = CpuStorage::rand_uniform(shape, dtype)?; let storage = CpuStorage::rand_uniform(shape, dtype, lo, up)?;
Ok(Storage::Cpu(storage)) Ok(Storage::Cpu(storage))
} }
Device::Cuda(device) => { Device::Cuda(device) => {
let storage = device.rand_uniform(shape, dtype)?; let storage = device.rand_uniform(shape, dtype, lo, up)?;
Ok(Storage::Cuda(storage)) Ok(Storage::Cuda(storage))
} }
} }

View File

@ -39,7 +39,7 @@ impl CudaDevice {
Err(Error::NotCompiledWithCudaSupport) Err(Error::NotCompiledWithCudaSupport)
} }
pub(crate) fn rand_uniform(&self, _: &Shape, _: DType) -> Result<CudaStorage> { pub(crate) fn rand_uniform(&self, _: &Shape, _: DType, _: f64, _: f64) -> Result<CudaStorage> {
Err(Error::NotCompiledWithCudaSupport) Err(Error::NotCompiledWithCudaSupport)
} }

View File

@ -226,19 +226,33 @@ impl Tensor {
s: S, s: S,
dtype: DType, dtype: DType,
device: &Device, device: &Device,
lo: f64,
up: f64,
is_variable: bool, is_variable: bool,
) -> Result<Self> { ) -> Result<Self> {
let s = s.into(); let s = s.into();
let storage = device.rand_uniform(&s, dtype)?; let storage = device.rand_uniform(&s, dtype, lo, up)?;
Ok(from_storage(storage, s, None, is_variable)) Ok(from_storage(storage, s, None, is_variable))
} }
pub fn rand_uniform<S: Into<Shape>>(s: S, dtype: DType, device: &Device) -> Result<Self> { pub fn rand_uniform<S: Into<Shape>>(
Self::rand_uniform_impl(s, dtype, device, false) s: S,
dtype: DType,
device: &Device,
lo: f64,
up: f64,
) -> Result<Self> {
Self::rand_uniform_impl(s, dtype, device, lo, up, false)
} }
pub fn rand_uniform_var<S: Into<Shape>>(s: S, dtype: DType, device: &Device) -> Result<Self> { pub fn rand_uniform_var<S: Into<Shape>>(
Self::rand_uniform_impl(s, dtype, device, true) s: S,
dtype: DType,
device: &Device,
lo: f64,
up: f64,
) -> Result<Self> {
Self::rand_uniform_impl(s, dtype, device, lo, up, true)
} }
fn rand_normal_impl<S: Into<Shape>>( fn rand_normal_impl<S: Into<Shape>>(