<commit_before>use std::error;
use std::fmt;
use std::mem;
use std::ptr;
use std::sync::Arc;
use std::sync::Mutex;

use device::Device;
use device::Queue;
use format::FormatDesc;
use image::Image;
use image::ImagePrototype;
use image::Type2d;
use image::Usage as ImageUsage;
use memory::ChunkProperties;
use memory::ChunkRange;
use memory::MemorySourceChunk;
use swapchain::CompositeAlpha;
use swapchain::PresentMode;
use swapchain::Surface;
use swapchain::SurfaceTransform;
use sync::Fence;
use sync::Semaphore;
use sync::SharingMode;

use check_errors;
use Error;
use OomError;
use Success;
use SynchronizedVulkanObject;
use VulkanObject;
use VulkanPointers;
use vk;

/// Contains the swapping system and the images that can be shown on a surface.
pub struct Swapchain {
    device: Arc<Device>,
    surface: Arc<Surface>,
    swapchain: vk::SwapchainKHR,

    images_semaphores: Mutex<Vec<Option<Arc<Semaphore>>>>,
}

impl Swapchain {
    /// Builds a new swapchain. Allocates images who content can be made visible on a surface.
    ///
    /// See also the `Surface::get_capabilities` function which returns the values that are
    /// supported by the implementation. All the parameters that you pass to `Swapchain::new`
    /// must be supported.
    ///
    /// The `clipped` parameter indicates whether the implementation is allowed to discard
    /// rendering operations that affect regions of the surface which aren't visible. This is
    /// important to take into account if your fragment shader has side-effects or if you want to
    /// read back the content of the image afterwards.
    ///
    /// This function returns the swapchain plus a list of the images that belong to the
    /// swapchain. The order in which the images are returned is important for the
    /// `acquire_next_image` and `present` functions.
    ///
    /// # Panic
    ///
    /// - Panicks if the device and the surface don't belong to the same instance.
    /// - Panicks if `color_attachment` is false in `usage`.
    ///
    pub fn new<F, S>(device: &Arc<Device>, surface: &Arc<Surface>, num_images: u32, format: F,
                     dimensions: [u32; 2], layers: u32, usage: &ImageUsage, sharing: S,
                     transform: SurfaceTransform, alpha: CompositeAlpha, mode: PresentMode,
                     clipped: bool) -> Result<(Arc<Swapchain>, Vec<ImagePrototype<Type2d, F, SwapchainAllocatedChunk>>), OomError>
        where F: FormatDesc + Clone, S: Into<SharingMode>
    {
        Swapchain::new_inner(device, surface, num_images, format, dimensions, layers, usage,
                             sharing, transform, alpha, mode, clipped)
    }

    // TODO:
    //pub fn recreate() { ... }

    fn new_inner<F, S>(device: &Arc<Device>, surface: &Arc<Surface>, num_images: u32, format: F,
                       dimensions: [u32; 2], layers: u32, usage: &ImageUsage, sharing: S,
                       transform: SurfaceTransform, alpha: CompositeAlpha, mode: PresentMode,
                       clipped: bool) -> Result<(Arc<Swapchain>, Vec<ImagePrototype<Type2d, F, SwapchainAllocatedChunk>>), OomError>
        where F: FormatDesc + Clone, S: Into<SharingMode>
    {
        // FIXME: check that the parameters are supported

        // FIXME: check that the device and the surface belong to the same instance
        let vk = device.pointers();

        assert!(usage.color_attachment);
        let usage = usage.to_usage_bits();

        let sharing = sharing.into();

        let swapchain = unsafe {
            let (sh_mode, sh_count, sh_indices) = match sharing {
                SharingMode::Exclusive(id) => (vk::SHARING_MODE_EXCLUSIVE, 0, ptr::null()),
                SharingMode::Concurrent(ref ids) => (vk::SHARING_MODE_CONCURRENT, ids.len() as u32,
                                                     ids.as_ptr()),
            };

            let infos = vk::SwapchainCreateInfoKHR {
                sType: vk::STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
                pNext: ptr::null(),
                flags: 0,   // reserved
                surface: surface.internal_object(),
                minImageCount: num_images,
                imageFormat: format.format() as u32,
                imageColorSpace: vk::COLORSPACE_SRGB_NONLINEAR_KHR,     // only available value
                imageExtent: vk::Extent2D { width: dimensions[0], height: dimensions[1] },
                imageArrayLayers: layers,
                imageUsage: usage,
                imageSharingMode: sh_mode,
                queueFamilyIndexCount: sh_count,
                pQueueFamilyIndices: sh_indices,
                preTransform: transform as u32,
                compositeAlpha: alpha as u32,
                presentMode: mode as u32,
                clipped: if clipped { vk::TRUE } else { vk::FALSE },
                oldSwapchain: 0,      // TODO:
            };

            let mut output = mem::uninitialized();
            try!(check_errors(vk.CreateSwapchainKHR(device.internal_object(), &infos,
                                                    ptr::null(), &mut output)));
            output
        };

        let swapchain = Arc::new(Swapchain {
            device: device.clone(),
            surface: surface.clone(),
            swapchain: swapchain,
            images_semaphores: Mutex::new(Vec::new()),
        });

        let images = unsafe {
            let mut num = 0;
            try!(check_errors(vk.GetSwapchainImagesKHR(device.internal_object(),
                                                       swapchain.swapchain, &mut num,
                                                       ptr::null_mut())));

            let mut images = Vec::with_capacity(num as usize);
            try!(check_errors(vk.GetSwapchainImagesKHR(device.internal_object(),
                                                       swapchain.swapchain, &mut num,
                                                       images.as_mut_ptr())));
            images.set_len(num as usize);
            images
        };

        let images = images.into_iter().enumerate().map(|(id, image)| unsafe {
            let mem = SwapchainAllocatedChunk { swapchain: swapchain.clone(), id: id };
            Image::from_raw_unowned(&device, image, mem, sharing.clone(), usage, format.clone(),
                                    dimensions, (), 1)
        }).collect::<Vec<_>>();

        {
            let mut semaphores = swapchain.images_semaphores.lock().unwrap();
            for _ in 0 .. images.len() {
                semaphores.push(None);
            }
        }

        Ok((swapchain, images))
    }

    /// Tries to take ownership of an image in order to draw on it.
    ///
    /// The function returns the index of the image in the array of images that was returned
    /// when creating the swapchain.
    ///
    /// If you try to draw on an image without acquiring it first, the execution will block. (TODO
    /// behavior may change).
    pub fn acquire_next_image(&self, timeout_ns: u64) -> Result<usize, AcquireError> {
        let vk = self.device.pointers();

        unsafe {
            let semaphore = Semaphore::new(&self.device).unwrap();      // TODO: error

            let mut out = mem::uninitialized();
            let r = try!(check_errors(vk.AcquireNextImageKHR(self.device.internal_object(),
                                                             self.swapchain, timeout_ns,
                                                             semaphore.internal_object(), 0,     // TODO: timeout
                                                             &mut out)));

            let id = match r {
                Success::Success => out as usize,
                Success::Suboptimal => out as usize,        // TODO: give that info to the user
                Success::NotReady => return Err(AcquireError::Timeout),
                Success::Timeout => return Err(AcquireError::Timeout),
                s => panic!("unexpected success value: {:?}", s)
            };

            let mut images_semaphores = self.images_semaphores.lock().unwrap();
            images_semaphores[id] = Some(semaphore);

            Ok(id)
        }
    }

    /// Presents an image on the screen.
    ///
    /// The parameter is the same index as what `acquire_next_image` returned. The image must
    /// have been acquired first.
    ///
    /// The actual behavior depends on the present mode that you passed when creating the
    /// swapchain.
    pub fn present(&self, queue: &Arc<Queue>, index: usize) -> Result<(), OomError> {     // FIXME: wrong error
        let vk = self.device.pointers();

        let wait_semaphore = {
            let mut images_semaphores = self.images_semaphores.lock().unwrap();
            images_semaphores[index].take()
        };

        // FIXME: the semaphore will be destroyed ; need to return it

        unsafe {
            let mut result = mem::uninitialized();

            let queue = queue.internal_object_guard();

            let index = index as u32;
            let infos = vk::PresentInfoKHR {
                sType: vk::STRUCTURE_TYPE_PRESENT_INFO_KHR,
                pNext: ptr::null(),
                waitSemaphoreCount: if let Some(_) = wait_semaphore { 1 } else { 0 },
                pWaitSemaphores: if let Some(ref sem) = wait_semaphore { &sem.internal_object() } else { ptr::null() },
                swapchainCount: 1,
                pSwapchains: &self.swapchain,
                pImageIndices: &index,
                pResults: &mut result,
            };

            try!(check_errors(vk.QueuePresentKHR(*queue, &infos)));
            try!(check_errors(result));
            Ok(())
        }
    }
}

impl Drop for Swapchain {
    #[inline]
    fn drop(&mut self) {
        unsafe {
            let vk = self.device.pointers();
            vk.DestroySwapchainKHR(self.device.internal_object(), self.swapchain, ptr::null());
        }
    }
}

/// Error that can happen when calling `acquire_next_image`.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[repr(u32)]
pub enum AcquireError {
    Timeout,
    SurfaceLost,
    OutOfDate,
}

impl error::Error for AcquireError {
    #[inline]
    fn description(&self) -> &str {
        match *self {
            AcquireError::Timeout => "no image is available for acquiring yet",
            AcquireError::SurfaceLost => "the surface of this swapchain is no longer valid",
            AcquireError::OutOfDate => "the swapchain needs to be recreated",
        }
    }
}

impl fmt::Display for AcquireError {
    #[inline]
    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        write!(fmt, "{}", error::Error::description(self))
    }
}

impl From<Error> for AcquireError {
    #[inline]
    fn from(err: Error) -> AcquireError {
        match err {
            Error::SurfaceLost => AcquireError::SurfaceLost,
            Error::OutOfDate => AcquireError::OutOfDate,
            _ => panic!("unexpected error: {:?}", err)
        }
    }
}

/// "Dummy" object used for images that indicates that they were allocated as part of a swapchain.
pub struct SwapchainAllocatedChunk {
    swapchain: Arc<Swapchain>,
    id: usize,
}

// FIXME: needs correct synchronization as well
unsafe impl MemorySourceChunk for SwapchainAllocatedChunk {
    #[inline]
    fn properties(&self) -> ChunkProperties {
        unreachable!()
    }

    #[inline]
    fn requires_fence(&self) -> bool { false }
    #[inline]
    fn requires_semaphore(&self) -> bool { true }
    #[inline]
    fn may_alias(&self) -> bool { false }

    #[inline]
    unsafe fn gpu_access(&self, _: bool, _: ChunkRange, _: &Arc<Queue>, _: Option<Arc<Fence>>,
                         post_semaphore: Option<Arc<Semaphore>>) -> Option<Arc<Semaphore>>
    {
        assert!(post_semaphore.is_some());
        // FIXME: must also check that image has been acquired
        let mut semaphores = self.swapchain.images_semaphores.lock().unwrap();
        let pre_semaphore = mem::replace(&mut semaphores[self.id], post_semaphore);
        pre_semaphore
    }
}
<commit_msg>Fix crash in release mode<commit_after>use std::error;
use std::fmt;
use std::mem;
use std::ptr;
use std::sync::Arc;
use std::sync::Mutex;

use device::Device;
use device::Queue;
use format::FormatDesc;
use image::Image;
use image::ImagePrototype;
use image::Type2d;
use image::Usage as ImageUsage;
use memory::ChunkProperties;
use memory::ChunkRange;
use memory::MemorySourceChunk;
use swapchain::CompositeAlpha;
use swapchain::PresentMode;
use swapchain::Surface;
use swapchain::SurfaceTransform;
use sync::Fence;
use sync::Semaphore;
use sync::SharingMode;

use check_errors;
use Error;
use OomError;
use Success;
use SynchronizedVulkanObject;
use VulkanObject;
use VulkanPointers;
use vk;

/// Contains the swapping system and the images that can be shown on a surface.
pub struct Swapchain {
    device: Arc<Device>,
    surface: Arc<Surface>,
    swapchain: vk::SwapchainKHR,

    images_semaphores: Mutex<Vec<Option<Arc<Semaphore>>>>,
}

impl Swapchain {
    /// Builds a new swapchain. Allocates images who content can be made visible on a surface.
    ///
    /// See also the `Surface::get_capabilities` function which returns the values that are
    /// supported by the implementation. All the parameters that you pass to `Swapchain::new`
    /// must be supported.
    ///
    /// The `clipped` parameter indicates whether the implementation is allowed to discard
    /// rendering operations that affect regions of the surface which aren't visible. This is
    /// important to take into account if your fragment shader has side-effects or if you want to
    /// read back the content of the image afterwards.
    ///
    /// This function returns the swapchain plus a list of the images that belong to the
    /// swapchain. The order in which the images are returned is important for the
    /// `acquire_next_image` and `present` functions.
    ///
    /// # Panic
    ///
    /// - Panicks if the device and the surface don't belong to the same instance.
    /// - Panicks if `color_attachment` is false in `usage`.
    ///
    pub fn new<F, S>(device: &Arc<Device>, surface: &Arc<Surface>, num_images: u32, format: F,
                     dimensions: [u32; 2], layers: u32, usage: &ImageUsage, sharing: S,
                     transform: SurfaceTransform, alpha: CompositeAlpha, mode: PresentMode,
                     clipped: bool) -> Result<(Arc<Swapchain>, Vec<ImagePrototype<Type2d, F, SwapchainAllocatedChunk>>), OomError>
        where F: FormatDesc + Clone, S: Into<SharingMode>
    {
        Swapchain::new_inner(device, surface, num_images, format, dimensions, layers, usage,
                             sharing, transform, alpha, mode, clipped)
    }

    // TODO:
    //pub fn recreate() { ... }

    fn new_inner<F, S>(device: &Arc<Device>, surface: &Arc<Surface>, num_images: u32, format: F,
                       dimensions: [u32; 2], layers: u32, usage: &ImageUsage, sharing: S,
                       transform: SurfaceTransform, alpha: CompositeAlpha, mode: PresentMode,
                       clipped: bool) -> Result<(Arc<Swapchain>, Vec<ImagePrototype<Type2d, F, SwapchainAllocatedChunk>>), OomError>
        where F: FormatDesc + Clone, S: Into<SharingMode>
    {
        // FIXME: check that the parameters are supported

        // FIXME: check that the device and the surface belong to the same instance
        let vk = device.pointers();

        assert!(usage.color_attachment);
        let usage = usage.to_usage_bits();

        let sharing = sharing.into();

        let swapchain = unsafe {
            let (sh_mode, sh_count, sh_indices) = match sharing {
                SharingMode::Exclusive(id) => (vk::SHARING_MODE_EXCLUSIVE, 0, ptr::null()),
                SharingMode::Concurrent(ref ids) => (vk::SHARING_MODE_CONCURRENT, ids.len() as u32,
                                                     ids.as_ptr()),
            };

            let infos = vk::SwapchainCreateInfoKHR {
                sType: vk::STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
                pNext: ptr::null(),
                flags: 0,   // reserved
                surface: surface.internal_object(),
                minImageCount: num_images,
                imageFormat: format.format() as u32,
                imageColorSpace: vk::COLORSPACE_SRGB_NONLINEAR_KHR,     // only available value
                imageExtent: vk::Extent2D { width: dimensions[0], height: dimensions[1] },
                imageArrayLayers: layers,
                imageUsage: usage,
                imageSharingMode: sh_mode,
                queueFamilyIndexCount: sh_count,
                pQueueFamilyIndices: sh_indices,
                preTransform: transform as u32,
                compositeAlpha: alpha as u32,
                presentMode: mode as u32,
                clipped: if clipped { vk::TRUE } else { vk::FALSE },
                oldSwapchain: 0,      // TODO:
            };

            let mut output = mem::uninitialized();
            try!(check_errors(vk.CreateSwapchainKHR(device.internal_object(), &infos,
                                                    ptr::null(), &mut output)));
            output
        };

        let swapchain = Arc::new(Swapchain {
            device: device.clone(),
            surface: surface.clone(),
            swapchain: swapchain,
            images_semaphores: Mutex::new(Vec::new()),
        });

        let images = unsafe {
            let mut num = 0;
            try!(check_errors(vk.GetSwapchainImagesKHR(device.internal_object(),
                                                       swapchain.swapchain, &mut num,
                                                       ptr::null_mut())));

            let mut images = Vec::with_capacity(num as usize);
            try!(check_errors(vk.GetSwapchainImagesKHR(device.internal_object(),
                                                       swapchain.swapchain, &mut num,
                                                       images.as_mut_ptr())));
            images.set_len(num as usize);
            images
        };

        let images = images.into_iter().enumerate().map(|(id, image)| unsafe {
            let mem = SwapchainAllocatedChunk { swapchain: swapchain.clone(), id: id };
            Image::from_raw_unowned(&device, image, mem, sharing.clone(), usage, format.clone(),
                                    dimensions, (), 1)
        }).collect::<Vec<_>>();

        {
            let mut semaphores = swapchain.images_semaphores.lock().unwrap();
            for _ in 0 .. images.len() {
                semaphores.push(None);
            }
        }

        Ok((swapchain, images))
    }

    /// Tries to take ownership of an image in order to draw on it.
    ///
    /// The function returns the index of the image in the array of images that was returned
    /// when creating the swapchain.
    ///
    /// If you try to draw on an image without acquiring it first, the execution will block. (TODO
    /// behavior may change).
    pub fn acquire_next_image(&self, timeout_ns: u64) -> Result<usize, AcquireError> {
        let vk = self.device.pointers();

        unsafe {
            let semaphore = Semaphore::new(&self.device).unwrap();      // TODO: error

            let mut out = mem::uninitialized();
            let r = try!(check_errors(vk.AcquireNextImageKHR(self.device.internal_object(),
                                                             self.swapchain, timeout_ns,
                                                             semaphore.internal_object(), 0,     // TODO: timeout
                                                             &mut out)));

            let id = match r {
                Success::Success => out as usize,
                Success::Suboptimal => out as usize,        // TODO: give that info to the user
                Success::NotReady => return Err(AcquireError::Timeout),
                Success::Timeout => return Err(AcquireError::Timeout),
                s => panic!("unexpected success value: {:?}", s)
            };

            let mut images_semaphores = self.images_semaphores.lock().unwrap();
            images_semaphores[id] = Some(semaphore);

            Ok(id)
        }
    }

    /// Presents an image on the screen.
    ///
    /// The parameter is the same index as what `acquire_next_image` returned. The image must
    /// have been acquired first.
    ///
    /// The actual behavior depends on the present mode that you passed when creating the
    /// swapchain.
    pub fn present(&self, queue: &Arc<Queue>, index: usize) -> Result<(), OomError> {     // FIXME: wrong error
        let vk = self.device.pointers();

        let wait_semaphore = {
            let mut images_semaphores = self.images_semaphores.lock().unwrap();
            images_semaphores[index].take()
        };

        // FIXME: the semaphore will be destroyed ; need to return it

        unsafe {
            let mut result = mem::uninitialized();

            let queue = queue.internal_object_guard();
            let semaphore = if let Some(ref sem) = wait_semaphore { sem.internal_object() } else { 0 };

            let index = index as u32;
            let infos = vk::PresentInfoKHR {
                sType: vk::STRUCTURE_TYPE_PRESENT_INFO_KHR,
                pNext: ptr::null(),
                waitSemaphoreCount: if let Some(_) = wait_semaphore { 1 } else { 0 },
                pWaitSemaphores: &semaphore,
                swapchainCount: 1,
                pSwapchains: &self.swapchain,
                pImageIndices: &index,
                pResults: &mut result,
            };

            try!(check_errors(vk.QueuePresentKHR(*queue, &infos)));
            //try!(check_errors(result));       // TODO: AMD driver doesn't seem to write the result
            Ok(())
        }
    }
}

impl Drop for Swapchain {
    #[inline]
    fn drop(&mut self) {
        unsafe {
            let vk = self.device.pointers();
            vk.DestroySwapchainKHR(self.device.internal_object(), self.swapchain, ptr::null());
        }
    }
}

/// Error that can happen when calling `acquire_next_image`.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[repr(u32)]
pub enum AcquireError {
    Timeout,
    SurfaceLost,
    OutOfDate,
}

impl error::Error for AcquireError {
    #[inline]
    fn description(&self) -> &str {
        match *self {
            AcquireError::Timeout => "no image is available for acquiring yet",
            AcquireError::SurfaceLost => "the surface of this swapchain is no longer valid",
            AcquireError::OutOfDate => "the swapchain needs to be recreated",
        }
    }
}

impl fmt::Display for AcquireError {
    #[inline]
    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        write!(fmt, "{}", error::Error::description(self))
    }
}

impl From<Error> for AcquireError {
    #[inline]
    fn from(err: Error) -> AcquireError {
        match err {
            Error::SurfaceLost => AcquireError::SurfaceLost,
            Error::OutOfDate => AcquireError::OutOfDate,
            _ => panic!("unexpected error: {:?}", err)
        }
    }
}

/// "Dummy" object used for images that indicates that they were allocated as part of a swapchain.
pub struct SwapchainAllocatedChunk {
    swapchain: Arc<Swapchain>,
    id: usize,
}

// FIXME: needs correct synchronization as well
unsafe impl MemorySourceChunk for SwapchainAllocatedChunk {
    #[inline]
    fn properties(&self) -> ChunkProperties {
        unreachable!()
    }

    #[inline]
    fn requires_fence(&self) -> bool { false }
    #[inline]
    fn requires_semaphore(&self) -> bool { true }
    #[inline]
    fn may_alias(&self) -> bool { false }

    #[inline]
    unsafe fn gpu_access(&self, _: bool, _: ChunkRange, _: &Arc<Queue>, _: Option<Arc<Fence>>,
                         post_semaphore: Option<Arc<Semaphore>>) -> Option<Arc<Semaphore>>
    {
        assert!(post_semaphore.is_some());
        // FIXME: must also check that image has been acquired
        let mut semaphores = self.swapchain.images_semaphores.lock().unwrap();
        let pre_semaphore = mem::replace(&mut semaphores[self.id], post_semaphore);
        pre_semaphore
    }
}
<|endoftext|>


<commit_before><commit_msg>Eliminate undefined behaviors due to box aliasing in IntoIter.<commit_after><|endoftext|>


<commit_before>/// MPI-based method for summing many arrays

// Argument parsing
// logging
#[macro_use] extern crate log;
#[macro_use] extern crate clap;
extern crate ndarray;
extern crate env_logger;
// lastly, this library
extern crate cabarrus;
use cabarrus::errors::*;
use ndarray::prelude::*;

pub fn main() {
    // Main can't return a Result, and the ? operator needs the enclosing function to return Result
    inner_main().expect("Could not recover. Exiting.");
}
pub fn inner_main() -> Result<()> {
    env_logger::init().unwrap();
    let args = app_from_crate!()
        .arg_from_usage("<size> 'how many workers there are'")
        .arg_from_usage("<rank> 'which worker am I, starting from 0'")
        .arg_from_usage("<addends>.. 'files containing matrices to add'")
        .arg_from_usage("<output> 'file in which to store the resulting matrix'")
        .get_matches();
    let outname = args.value_of("output").unwrap();
    let mut mats : Vec<&str> = args.values_of("addends").unwrap().collect();
    mats.sort();

    let size = value_t!(args, "size", usize).unwrap_or_else(|e| e.exit());
    let rank = value_t!(args, "rank", usize).unwrap_or_else(|e| e.exit());
    let chunksize = (mats.len() + size - 1) / size;
    mats = mats.into_iter().skip(rank*chunksize).take(chunksize).collect();
    info!("{} files, {} workers (I'm #{}), chunks of {} (I get {}), output goes to {}",
        mats.len(), size, rank, chunksize, mats.len(), outname);

    if ! mats.is_empty() {
        {
            let matname = mats[0];
            let ref matfile = cabarrus::numpy::open_matrix_mmap(matname)
                .expect(&format!("Failed to open first matrix, {}", matname));
            let ref mat = cabarrus::numpy::read_matrix_mmap(matfile)
                .unwrap();
            cabarrus::numpy::write_matrix(outname, mat)
                .expect("Failed to create accumulator matrix file");
        };
        let ref accumfile = cabarrus::numpy::open_matrix_mmap(outname)
            .expect("Failed to reopen accumulator matrix");
        let mut accum = cabarrus::numpy::read_matrix_mmap(accumfile)?;
        let height = accum.shape()[0];

        // This is awkward because the matrices are too large for memory..
        // But if accum is an mmap, you waste a *ton* of IO.
        let mut bufline = Array1::zeros([accum.shape()[1]]);
        for matnames in mats[1..].chunks(16) {
            info!("Working on {:?}", matnames);
            let matfiles : Vec<cabarrus::numpy::MatFile> =
                matnames.iter()
                .map(|name| cabarrus::numpy::open_matrix_mmap(name)
                    .expect(&format!("Failed to open matrix {}", name)))
                .collect();
            let mats : Vec<ArrayViewMut2<f64>> = matfiles.iter()
                .map(|matfile| cabarrus::numpy::read_matrix_mmap(matfile)
                    .expect("Failed to read matrix"))
                .collect();

            // The overhead just doesn't matter when the IO is the limit

            for (row_i, mut accum_row) in accum.outer_iter_mut().enumerate() {
                if row_i % (height / 20) == 0 {
                    info!("Finished {}%", 100.0 * row_i as f64 / height as f64);
                }
                bufline *= 0.0;
                for mat in mats.iter() {
                    bufline += &mat.row(row_i);
                }
                accum_row.assign(&bufline);
            }
            //info!("Reading {} ({} GB) ..", matname, mat.len() >> 27);
        }
    } else {
        info!("No matrices processed so nothing saved.");
    }
    Ok(())
}
<commit_msg>operate adds in large chunks<commit_after>/// MPI-based method for summing many arrays

// Argument parsing
// logging
#[macro_use] extern crate log;
#[macro_use] extern crate clap;
#[macro_use] extern crate ndarray;
extern crate env_logger;
// lastly, this library
extern crate cabarrus;
use cabarrus::errors::*;
use ndarray::prelude::*;

pub fn main() {
    // Main can't return a Result, and the ? operator needs the enclosing function to return Result
    inner_main().expect("Could not recover. Exiting.");
}
pub fn inner_main() -> Result<()> {
    env_logger::init().unwrap();
    let args = app_from_crate!()
        .arg_from_usage("<size> 'how many workers there are'")
        .arg_from_usage("<rank> 'which worker am I, starting from 0'")
        .arg_from_usage("<addends>.. 'files containing matrices to add'")
        .arg_from_usage("<output> 'file in which to store the resulting matrix'")
        .get_matches();
    let outname = args.value_of("output").unwrap();
    let mut mats : Vec<&str> = args.values_of("addends").unwrap().collect();
    mats.sort();

    let size = value_t!(args, "size", usize).unwrap_or_else(|e| e.exit());
    let rank = value_t!(args, "rank", usize).unwrap_or_else(|e| e.exit());
    let chunksize = (mats.len() + size - 1) / size;
    mats = mats.into_iter().skip(rank*chunksize).take(chunksize).collect();
    info!("{} files, {} workers (I'm #{}), chunks of {} (I get {}), output goes to {}",
        mats.len(), size, rank, chunksize, mats.len(), outname);

    if ! mats.is_empty() {
        {
            let matname = mats[0];
            let ref matfile = cabarrus::numpy::open_matrix_mmap(matname)
                .expect(&format!("Failed to open first matrix, {}", matname));
            let ref mat = cabarrus::numpy::read_matrix_mmap(matfile)
                .unwrap();
            cabarrus::numpy::write_matrix(outname, mat)
                .expect("Failed to create accumulator matrix file");
        };
        let ref accumfile = cabarrus::numpy::open_matrix_mmap(outname)
            .expect("Failed to reopen accumulator matrix");
        let mut accum = cabarrus::numpy::read_matrix_mmap(accumfile)?;

        // This is awkward because the matrices are too large for memory..
        // But if accum is an mmap, you waste a *ton* of IO otherwise.
        // Get chunks of about 1 GB
        let capacity = std::cmp::max(1, (1 << 27) / accum.len_of(Axis(1)));
        let mut bufchunk = Array2::zeros([capacity, accum.len_of(Axis(1))]);

        // 1024 files at a time
        for matnames in mats[1..].chunks(1024) {
            info!("Working on {:?}", matnames);
            let matfiles : Vec<cabarrus::numpy::MatFile> =
                matnames.iter()
                .map(|name| cabarrus::numpy::open_matrix_mmap(name)
                    .expect(&format!("Failed to open matrix {}", name)))
                .collect();
            let mats : Vec<ArrayViewMut2<f64>> = matfiles.iter()
                .map(|matfile| cabarrus::numpy::read_matrix_mmap(matfile)
                    .expect("Failed to read matrix"))
                .collect();

            // The overhead just doesn't matter when the IO is the limit
            let mut row_i = 0 as isize;
            while row_i < accum.len_of(Axis(0)) as isize {
                let fill = std::cmp::min(capacity, accum.len_of(Axis(0))) as isize - row_i;

                bufchunk *= 0.0;
                let mut buf = bufchunk.slice_mut(s![..fill, ..]);
                for mat in mats.iter() {
                    buf += &mat.slice(s![row_i..row_i+fill, ..]);
                }
                let mut accum_chunk = accum.slice_mut(s![row_i..row_i+fill, ..]);
                accum_chunk += &buf;

                row_i += fill;
            }

           /* for (row_i, mut accum_row) in accum.outer_iter_mut().enumerate() {
                if row_i % (height / 20) == 0 {
                    info!("Finished {}%", 100.0 * row_i as f64 / height as f64);
                }
                bufline *= 0.0;
                for mat in mats.iter() {
                    bufline += &mat.row(row_i);
                }
                accum_row += &bufline;
            }*/

            //info!("Reading {} ({} GB) ..", matname, mat.len() >> 27);
        }
    } else {
        info!("No matrices processed so nothing saved.");
    }
    Ok(())
}
<|endoftext|>


<commit_before>#[macro_use] extern crate log;
#[macro_use] extern crate version;
extern crate clap;
extern crate chrono;

extern crate libimagdiary;
extern crate libimagentrylist;
extern crate libimagentryview;
extern crate libimaginteraction;
extern crate libimagrt;
extern crate libimagstore;
extern crate libimagutil;
extern crate libimagtimeui;
#[macro_use] extern crate libimagerror;

use std::process::exit;

use libimagrt::runtime::Runtime;

mod create;
mod delete;
mod edit;
mod list;
mod ui;
mod util;
mod view;

use create::create;
use delete::delete;
use edit::edit;
use list::list;
use ui::build_ui;
use view::view;

fn main() {
    let name = "imag-diary";
    let version = &version!()[..];
    let about = "Personal Diary/Diaries";
    let ui = build_ui(Runtime::get_default_cli_builder(name, version, about));
    let rt = {
        let rt = Runtime::new(ui);
        if rt.is_ok() {
            rt.unwrap()
        } else {
            println!("Could not set up Runtime");
            println!("{:?}", rt.err().unwrap());
            exit(1);
        }
    };

    rt.cli()
        .subcommand_name()
        .map(|name| {
            debug!("Call {}", name);
            match name {
                "create" => create(&rt),
                "delete" => delete(&rt),
                "edit" => edit(&rt),
                "list" => list(&rt),
                "diary" => diary(&rt),
                "view" => view(&rt),
                _        => {
                    debug!("Unknown command"); // More error handling
                },
            }
        });
}

fn diary(rt: &Runtime) {
    unimplemented!()
}

<commit_msg>Remove unused function<commit_after>#[macro_use] extern crate log;
#[macro_use] extern crate version;
extern crate clap;
extern crate chrono;

extern crate libimagdiary;
extern crate libimagentrylist;
extern crate libimagentryview;
extern crate libimaginteraction;
extern crate libimagrt;
extern crate libimagstore;
extern crate libimagutil;
extern crate libimagtimeui;
#[macro_use] extern crate libimagerror;

use std::process::exit;

use libimagrt::runtime::Runtime;

mod create;
mod delete;
mod edit;
mod list;
mod ui;
mod util;
mod view;

use create::create;
use delete::delete;
use edit::edit;
use list::list;
use ui::build_ui;
use view::view;

fn main() {
    let name = "imag-diary";
    let version = &version!()[..];
    let about = "Personal Diary/Diaries";
    let ui = build_ui(Runtime::get_default_cli_builder(name, version, about));
    let rt = {
        let rt = Runtime::new(ui);
        if rt.is_ok() {
            rt.unwrap()
        } else {
            println!("Could not set up Runtime");
            println!("{:?}", rt.err().unwrap());
            exit(1);
        }
    };

    rt.cli()
        .subcommand_name()
        .map(|name| {
            debug!("Call {}", name);
            match name {
                "create" => create(&rt),
                "delete" => delete(&rt),
                "edit" => edit(&rt),
                "list" => list(&rt),
                "view" => view(&rt),
                _        => {
                    debug!("Unknown command"); // More error handling
                },
            }
        });
}

<|endoftext|>


<commit_before>#[macro_use]
extern crate bencher;
extern crate rand;
extern crate ropey;

use bencher::Bencher;
use rand::random;
use ropey::Rope;

const TEXT: &str = include_str!("large.txt");
const SMALL_TEXT: &str = include_str!("small.txt");

//----

fn byte_to_char(bench: &mut Bencher) {
    let rope = Rope::from_str(TEXT);
    let len = rope.len_bytes();
    bench.iter(|| {
        rope.byte_to_char(random::<usize>() % (len + 1));
    })
}

fn byte_to_line(bench: &mut Bencher) {
    let rope = Rope::from_str(TEXT);
    let len = rope.len_bytes();
    bench.iter(|| {
        rope.byte_to_line(random::<usize>() % (len + 1));
    })
}

fn char_to_byte(bench: &mut Bencher) {
    let rope = Rope::from_str(TEXT);
    let len = rope.len_chars();
    bench.iter(|| {
        rope.char_to_byte(random::<usize>() % (len + 1));
    })
}

fn char_to_line(bench: &mut Bencher) {
    let rope = Rope::from_str(TEXT);
    let len = rope.len_chars();
    bench.iter(|| {
        rope.char_to_line(random::<usize>() % (len + 1));
    })
}

fn line_to_byte(bench: &mut Bencher) {
    let rope = Rope::from_str(TEXT);
    let len = rope.len_lines();
    bench.iter(|| {
        rope.line_to_byte(random::<usize>() % (len + 1));
    })
}

fn line_to_char(bench: &mut Bencher) {
    let rope = Rope::from_str(TEXT);
    let len = rope.len_lines();
    bench.iter(|| {
        rope.line_to_char(random::<usize>() % (len + 1));
    })
}

//----

fn get_char(bench: &mut Bencher) {
    let rope = Rope::from_str(TEXT);
    let len = rope.len_chars();
    bench.iter(|| {
        rope.char(random::<usize>() % len);
    })
}

fn get_line(bench: &mut Bencher) {
    let rope = Rope::from_str(TEXT);
    let len = rope.len_lines();
    bench.iter(|| {
        rope.line(random::<usize>() % len);
    })
}

fn chunk_at_byte(bench: &mut Bencher) {
    let rope = Rope::from_str(TEXT);
    let len = rope.len_bytes();
    bench.iter(|| {
        rope.chunk_at_byte(random::<usize>() % (len + 1));
    })
}

fn chunk_at_byte_slice(bench: &mut Bencher) {
    let rope = Rope::from_str(TEXT);
    let slice = rope.slice(324..(rope.len_chars() - 213));
    let len = slice.len_bytes();
    bench.iter(|| {
        slice.chunk_at_byte(random::<usize>() % (len + 1));
    })
}

fn chunk_at_char(bench: &mut Bencher) {
    let rope = Rope::from_str(TEXT);
    let len = rope.len_chars();
    bench.iter(|| {
        rope.chunk_at_char(random::<usize>() % (len + 1));
    })
}

fn chunk_at_char_slice(bench: &mut Bencher) {
    let rope = Rope::from_str(TEXT);
    let slice = rope.slice(324..(rope.len_chars() - 213));
    let len = slice.len_chars();
    bench.iter(|| {
        slice.chunk_at_char(random::<usize>() % (len + 1));
    })
}

//----

fn slice(bench: &mut Bencher) {
    let rope = Rope::from_str(TEXT);
    let len = rope.len_chars();
    bench.iter(|| {
        let mut start = random::<usize>() % (len + 1);
        let mut end = random::<usize>() % (len + 1);
        if start > end {
            std::mem::swap(&mut start, &mut end);
        }
        rope.slice(start..end);
    })
}

fn slice_small(bench: &mut Bencher) {
    let rope = Rope::from_str(TEXT);
    let len = rope.len_chars();
    bench.iter(|| {
        let mut start = random::<usize>() % (len + 1);
        if start > (len - 65) {
            start = len - 65;
        }
        let end = start + 64;
        rope.slice(start..end);
    })
}

fn slice_from_small_rope(bench: &mut Bencher) {
    let rope = Rope::from_str(SMALL_TEXT);
    let len = rope.len_chars();
    bench.iter(|| {
        let mut start = random::<usize>() % (len + 1);
        let mut end = random::<usize>() % (len + 1);
        if start > end {
            std::mem::swap(&mut start, &mut end);
        }
        rope.slice(start..end);
    })
}

fn slice_whole_rope(bench: &mut Bencher) {
    let rope = Rope::from_str(TEXT);
    bench.iter(|| {
        rope.slice(..);
    })
}

fn slice_whole_slice(bench: &mut Bencher) {
    let rope = Rope::from_str(TEXT);
    let len = rope.len_chars();
    let slice = rope.slice(1..len - 1);
    bench.iter(|| {
        slice.slice(..);
    })
}

//----

benchmark_group!(
    benches,
    byte_to_char,
    byte_to_line,
    char_to_byte,
    char_to_line,
    line_to_byte,
    line_to_char,
    get_char,
    get_line,
    chunk_at_byte,
    chunk_at_byte_slice,
    chunk_at_char,
    chunk_at_char_slice,
    slice,
    slice_small,
    slice_from_small_rope,
    slice_whole_rope,
    slice_whole_slice
);
benchmark_main!(benches);
<commit_msg>Added benchmarks for chunk_at_line_break() methods.<commit_after>#[macro_use]
extern crate bencher;
extern crate rand;
extern crate ropey;

use bencher::Bencher;
use rand::random;
use ropey::Rope;

const TEXT: &str = include_str!("large.txt");
const SMALL_TEXT: &str = include_str!("small.txt");

//----

fn byte_to_char(bench: &mut Bencher) {
    let rope = Rope::from_str(TEXT);
    let len = rope.len_bytes();
    bench.iter(|| {
        rope.byte_to_char(random::<usize>() % (len + 1));
    })
}

fn byte_to_line(bench: &mut Bencher) {
    let rope = Rope::from_str(TEXT);
    let len = rope.len_bytes();
    bench.iter(|| {
        rope.byte_to_line(random::<usize>() % (len + 1));
    })
}

fn char_to_byte(bench: &mut Bencher) {
    let rope = Rope::from_str(TEXT);
    let len = rope.len_chars();
    bench.iter(|| {
        rope.char_to_byte(random::<usize>() % (len + 1));
    })
}

fn char_to_line(bench: &mut Bencher) {
    let rope = Rope::from_str(TEXT);
    let len = rope.len_chars();
    bench.iter(|| {
        rope.char_to_line(random::<usize>() % (len + 1));
    })
}

fn line_to_byte(bench: &mut Bencher) {
    let rope = Rope::from_str(TEXT);
    let len = rope.len_lines();
    bench.iter(|| {
        rope.line_to_byte(random::<usize>() % (len + 1));
    })
}

fn line_to_char(bench: &mut Bencher) {
    let rope = Rope::from_str(TEXT);
    let len = rope.len_lines();
    bench.iter(|| {
        rope.line_to_char(random::<usize>() % (len + 1));
    })
}

//----

fn get_char(bench: &mut Bencher) {
    let rope = Rope::from_str(TEXT);
    let len = rope.len_chars();
    bench.iter(|| {
        rope.char(random::<usize>() % len);
    })
}

fn get_line(bench: &mut Bencher) {
    let rope = Rope::from_str(TEXT);
    let len = rope.len_lines();
    bench.iter(|| {
        rope.line(random::<usize>() % len);
    })
}

fn chunk_at_byte(bench: &mut Bencher) {
    let rope = Rope::from_str(TEXT);
    let len = rope.len_bytes();
    bench.iter(|| {
        rope.chunk_at_byte(random::<usize>() % (len + 1));
    })
}

fn chunk_at_byte_slice(bench: &mut Bencher) {
    let rope = Rope::from_str(TEXT);
    let slice = rope.slice(324..(rope.len_chars() - 213));
    let len = slice.len_bytes();
    bench.iter(|| {
        slice.chunk_at_byte(random::<usize>() % (len + 1));
    })
}

fn chunk_at_char(bench: &mut Bencher) {
    let rope = Rope::from_str(TEXT);
    let len = rope.len_chars();
    bench.iter(|| {
        rope.chunk_at_char(random::<usize>() % (len + 1));
    })
}

fn chunk_at_char_slice(bench: &mut Bencher) {
    let rope = Rope::from_str(TEXT);
    let slice = rope.slice(324..(rope.len_chars() - 213));
    let len = slice.len_chars();
    bench.iter(|| {
        slice.chunk_at_char(random::<usize>() % (len + 1));
    })
}

fn chunk_at_line_break(bench: &mut Bencher) {
    let rope = Rope::from_str(TEXT);
    let len = rope.len_lines();
    bench.iter(|| {
        rope.chunk_at_line_break(random::<usize>() % (len + 1));
    })
}

fn chunk_at_line_break_slice(bench: &mut Bencher) {
    let rope = Rope::from_str(TEXT);
    let slice = rope.slice(324..(rope.len_chars() - 213));
    let len = slice.len_lines();
    bench.iter(|| {
        slice.chunk_at_line_break(random::<usize>() % (len + 1));
    })
}

//----

fn slice(bench: &mut Bencher) {
    let rope = Rope::from_str(TEXT);
    let len = rope.len_chars();
    bench.iter(|| {
        let mut start = random::<usize>() % (len + 1);
        let mut end = random::<usize>() % (len + 1);
        if start > end {
            std::mem::swap(&mut start, &mut end);
        }
        rope.slice(start..end);
    })
}

fn slice_small(bench: &mut Bencher) {
    let rope = Rope::from_str(TEXT);
    let len = rope.len_chars();
    bench.iter(|| {
        let mut start = random::<usize>() % (len + 1);
        if start > (len - 65) {
            start = len - 65;
        }
        let end = start + 64;
        rope.slice(start..end);
    })
}

fn slice_from_small_rope(bench: &mut Bencher) {
    let rope = Rope::from_str(SMALL_TEXT);
    let len = rope.len_chars();
    bench.iter(|| {
        let mut start = random::<usize>() % (len + 1);
        let mut end = random::<usize>() % (len + 1);
        if start > end {
            std::mem::swap(&mut start, &mut end);
        }
        rope.slice(start..end);
    })
}

fn slice_whole_rope(bench: &mut Bencher) {
    let rope = Rope::from_str(TEXT);
    bench.iter(|| {
        rope.slice(..);
    })
}

fn slice_whole_slice(bench: &mut Bencher) {
    let rope = Rope::from_str(TEXT);
    let len = rope.len_chars();
    let slice = rope.slice(1..len - 1);
    bench.iter(|| {
        slice.slice(..);
    })
}

//----

benchmark_group!(
    benches,
    byte_to_char,
    byte_to_line,
    char_to_byte,
    char_to_line,
    line_to_byte,
    line_to_char,
    get_char,
    get_line,
    chunk_at_byte,
    chunk_at_byte_slice,
    chunk_at_char,
    chunk_at_char_slice,
    chunk_at_line_break,
    chunk_at_line_break_slice,
    slice,
    slice_small,
    slice_from_small_rope,
    slice_whole_rope,
    slice_whole_slice
);
benchmark_main!(benches);
<|endoftext|>


<commit_before>#[macro_use]
extern crate simple_bitfield;

simple_bitfield! {
    FooBar, u32, // newtype name, underlying type
    // getter name, setter name: msb (included), lsb
    foo1, set_foo1: 0, 0,
    foo2, set_foo2: 31, 31,
    foo3, set_foo3: 3, 0,
    foo4, set_foo4: 31, 28,
    // getter name, setter name: msb of first element (included), lsb of first element; count
    foo5, set_foo5: 0, 0; 32,
    foo6, set_foo6: 5, 3; 3,
    getter_only, _: 3, 1,
    _, setter_only: 4, 2,
    getter_only_array, _: 5, 3; 3,
    _, setter_only_array: 6, 4; 3,
    all_bits, set_all_bits: 31, 0,
}

#[test]
fn test_single_bit() {
    let mut fb = FooBar(0);

    fb.set_foo1(1);
    assert_eq!(0x1, fb.0);
    assert_eq!(0x1, fb.foo1());
    assert_eq!(0x0, fb.foo2());

    fb.set_foo2(1);
    assert_eq!(0x80000001, fb.0);
    assert_eq!(0x1, fb.foo1());
    assert_eq!(0x1, fb.foo2());

    fb.set_foo1(0);
    assert_eq!(0x80000000, fb.0);
    assert_eq!(0x0, fb.foo1());
    assert_eq!(0x1, fb.foo2());
}

#[test]
fn test_single_bit_plus_garbage() {
    let mut fb = FooBar(0);

    fb.set_foo1(0b10);
    assert_eq!(0x0, fb.0);
    assert_eq!(0x0, fb.foo1());
    assert_eq!(0x0, fb.foo2());

    fb.set_foo1(0b11);
    assert_eq!(0x1, fb.0);
    assert_eq!(0x1, fb.foo1());
    assert_eq!(0x0, fb.foo2());

}

#[test]
fn test_multiple_bit() {
    let mut fb = FooBar(0);

    fb.set_foo3(0x0F);
    assert_eq!(0xF, fb.0);
    assert_eq!(0xF, fb.foo3());
    assert_eq!(0x0, fb.foo4());

    fb.set_foo4(0x0F);
    assert_eq!(0xF000000F, fb.0);
    assert_eq!(0xF, fb.foo3());
    assert_eq!(0xF, fb.foo4());

    fb.set_foo3(0);
    assert_eq!(0xF0000000, fb.0);
    assert_eq!(0x0, fb.foo3());
    assert_eq!(0xF, fb.foo4());

    fb.set_foo3(0xA);
    assert_eq!(0xF000000A, fb.0);
    assert_eq!(0xA, fb.foo3());
    assert_eq!(0xF, fb.foo4());
}

#[test]
fn test_getter_setter_only() {
    let mut fb = FooBar(0);
    fb.setter_only(0x7);
    assert_eq!(0x1C, fb.0);
    assert_eq!(0x6, fb.getter_only());
}

#[test]
fn test_array_field1() {
    let mut fb = FooBar(0);

    fb.set_foo5(0, 1);
    assert_eq!(0x1, fb.0);
    assert_eq!(1, fb.foo5(0));

    fb.set_foo5(0, 0);
    assert_eq!(0x0, fb.0);
    assert_eq!(0, fb.foo5(0));

    fb.set_foo5(0, 1);
    fb.set_foo5(6, 1);
    fb.set_foo5(31, 1);
    assert_eq!(0x80000041, fb.0);
    assert_eq!(1, fb.foo5(0));
    assert_eq!(1, fb.foo5(6));
    assert_eq!(1, fb.foo5(31));
    assert_eq!(0, fb.foo5(1));
    assert_eq!(0, fb.foo5(5));
    assert_eq!(0, fb.foo5(7));
    assert_eq!(0, fb.foo5(30));
}

#[test]
fn test_array_field2() {
    let mut fb = FooBar(0);

    fb.set_foo6(0, 1);
    assert_eq!(0x8, fb.0);
    assert_eq!(1, fb.foo6(0));
    assert_eq!(0, fb.foo6(1));
    assert_eq!(0, fb.foo6(2));

    fb.set_foo6(0, 7);
    assert_eq!(0x38, fb.0);
    assert_eq!(7, fb.foo6(0));
    assert_eq!(0, fb.foo6(1));
    assert_eq!(0, fb.foo6(2));

    fb.set_foo6(2, 7);
    assert_eq!(0xE38, fb.0);
    assert_eq!(7, fb.foo6(0));
    assert_eq!(0, fb.foo6(1));
    assert_eq!(7, fb.foo6(2));

    fb.set_foo6(0, 0);
    assert_eq!(0xE00, fb.0);
    assert_eq!(0, fb.foo6(0));
    assert_eq!(0, fb.foo6(1));
    assert_eq!(7, fb.foo6(2));
}

#[test]
fn test_all_bits() {
    let mut fb = FooBar(0);

    assert_eq!(0, fb.all_bits());

    fb.set_all_bits(!0u32);
    assert_eq!(!0u32, fb.0);
    assert_eq!(!0u32, fb.all_bits());

    fb.0 = 0x80000001;
    assert_eq!(0x80000001, fb.all_bits());
}

simple_bitfield! {
    ArrayBitfiled, [u8],
    foo1, set_foo1: 0, 0,
    foo2, set_foo2: 7, 0,
    foo3, set_foo3: 8, 1,
    foo4, set_foo4: 20, 4,
}

#[test]
fn test_arraybitfield() {
    let mut ab = ArrayBitfiled([0; 3]);

    assert_eq!(0, ab.foo1());
    assert_eq!(0, ab.foo2());
    assert_eq!(0, ab.foo3());
    assert_eq!(0, ab.foo4());

    ab.set_foo1(1);
    assert_eq!([1, 0, 0], ab.0);
    assert_eq!(1, ab.foo1());
    assert_eq!(1, ab.foo2());
    assert_eq!(0, ab.foo3());
    assert_eq!(0, ab.foo4());

    ab.set_foo1(0);
    ab.set_foo2(0xFF);
    assert_eq!([0xFF, 0, 0], ab.0);
    assert_eq!(1, ab.foo1());
    assert_eq!(0xFF, ab.foo2());
    assert_eq!(0x7F, ab.foo3());
    assert_eq!(0x0F, ab.foo4());

    ab.set_foo2(0);
    ab.set_foo3(0xFF);
    assert_eq!([0xFE, 0x1, 0], ab.0);
    assert_eq!(0, ab.foo1());
    assert_eq!(0xFE, ab.foo2());
    assert_eq!(0xFF, ab.foo3());
    assert_eq!(0x1F, ab.foo4());

    ab.set_foo3(0);
    ab.set_foo4(0xFFFF);
    assert_eq!([0xF0, 0xFF, 0x0F], ab.0);
    assert_eq!(0, ab.foo1());
    assert_eq!(0xF0, ab.foo2());
    assert_eq!(0xF8, ab.foo3());
    assert_eq!(0xFFFF, ab.foo4());
}
<commit_msg>Fix typo in type name<commit_after>#[macro_use]
extern crate simple_bitfield;

simple_bitfield! {
    FooBar, u32, // newtype name, underlying type
    // getter name, setter name: msb (included), lsb
    foo1, set_foo1: 0, 0,
    foo2, set_foo2: 31, 31,
    foo3, set_foo3: 3, 0,
    foo4, set_foo4: 31, 28,
    // getter name, setter name: msb of first element (included), lsb of first element; count
    foo5, set_foo5: 0, 0; 32,
    foo6, set_foo6: 5, 3; 3,
    getter_only, _: 3, 1,
    _, setter_only: 4, 2,
    getter_only_array, _: 5, 3; 3,
    _, setter_only_array: 6, 4; 3,
    all_bits, set_all_bits: 31, 0,
}

#[test]
fn test_single_bit() {
    let mut fb = FooBar(0);

    fb.set_foo1(1);
    assert_eq!(0x1, fb.0);
    assert_eq!(0x1, fb.foo1());
    assert_eq!(0x0, fb.foo2());

    fb.set_foo2(1);
    assert_eq!(0x80000001, fb.0);
    assert_eq!(0x1, fb.foo1());
    assert_eq!(0x1, fb.foo2());

    fb.set_foo1(0);
    assert_eq!(0x80000000, fb.0);
    assert_eq!(0x0, fb.foo1());
    assert_eq!(0x1, fb.foo2());
}

#[test]
fn test_single_bit_plus_garbage() {
    let mut fb = FooBar(0);

    fb.set_foo1(0b10);
    assert_eq!(0x0, fb.0);
    assert_eq!(0x0, fb.foo1());
    assert_eq!(0x0, fb.foo2());

    fb.set_foo1(0b11);
    assert_eq!(0x1, fb.0);
    assert_eq!(0x1, fb.foo1());
    assert_eq!(0x0, fb.foo2());

}

#[test]
fn test_multiple_bit() {
    let mut fb = FooBar(0);

    fb.set_foo3(0x0F);
    assert_eq!(0xF, fb.0);
    assert_eq!(0xF, fb.foo3());
    assert_eq!(0x0, fb.foo4());

    fb.set_foo4(0x0F);
    assert_eq!(0xF000000F, fb.0);
    assert_eq!(0xF, fb.foo3());
    assert_eq!(0xF, fb.foo4());

    fb.set_foo3(0);
    assert_eq!(0xF0000000, fb.0);
    assert_eq!(0x0, fb.foo3());
    assert_eq!(0xF, fb.foo4());

    fb.set_foo3(0xA);
    assert_eq!(0xF000000A, fb.0);
    assert_eq!(0xA, fb.foo3());
    assert_eq!(0xF, fb.foo4());
}

#[test]
fn test_getter_setter_only() {
    let mut fb = FooBar(0);
    fb.setter_only(0x7);
    assert_eq!(0x1C, fb.0);
    assert_eq!(0x6, fb.getter_only());
}

#[test]
fn test_array_field1() {
    let mut fb = FooBar(0);

    fb.set_foo5(0, 1);
    assert_eq!(0x1, fb.0);
    assert_eq!(1, fb.foo5(0));

    fb.set_foo5(0, 0);
    assert_eq!(0x0, fb.0);
    assert_eq!(0, fb.foo5(0));

    fb.set_foo5(0, 1);
    fb.set_foo5(6, 1);
    fb.set_foo5(31, 1);
    assert_eq!(0x80000041, fb.0);
    assert_eq!(1, fb.foo5(0));
    assert_eq!(1, fb.foo5(6));
    assert_eq!(1, fb.foo5(31));
    assert_eq!(0, fb.foo5(1));
    assert_eq!(0, fb.foo5(5));
    assert_eq!(0, fb.foo5(7));
    assert_eq!(0, fb.foo5(30));
}

#[test]
fn test_array_field2() {
    let mut fb = FooBar(0);

    fb.set_foo6(0, 1);
    assert_eq!(0x8, fb.0);
    assert_eq!(1, fb.foo6(0));
    assert_eq!(0, fb.foo6(1));
    assert_eq!(0, fb.foo6(2));

    fb.set_foo6(0, 7);
    assert_eq!(0x38, fb.0);
    assert_eq!(7, fb.foo6(0));
    assert_eq!(0, fb.foo6(1));
    assert_eq!(0, fb.foo6(2));

    fb.set_foo6(2, 7);
    assert_eq!(0xE38, fb.0);
    assert_eq!(7, fb.foo6(0));
    assert_eq!(0, fb.foo6(1));
    assert_eq!(7, fb.foo6(2));

    fb.set_foo6(0, 0);
    assert_eq!(0xE00, fb.0);
    assert_eq!(0, fb.foo6(0));
    assert_eq!(0, fb.foo6(1));
    assert_eq!(7, fb.foo6(2));
}

#[test]
fn test_all_bits() {
    let mut fb = FooBar(0);

    assert_eq!(0, fb.all_bits());

    fb.set_all_bits(!0u32);
    assert_eq!(!0u32, fb.0);
    assert_eq!(!0u32, fb.all_bits());

    fb.0 = 0x80000001;
    assert_eq!(0x80000001, fb.all_bits());
}

simple_bitfield! {
    ArrayBitfield, [u8],
    foo1, set_foo1: 0, 0,
    foo2, set_foo2: 7, 0,
    foo3, set_foo3: 8, 1,
    foo4, set_foo4: 20, 4,
}

#[test]
fn test_arraybitfield() {
    let mut ab = ArrayBitfield([0; 3]);

    assert_eq!(0, ab.foo1());
    assert_eq!(0, ab.foo2());
    assert_eq!(0, ab.foo3());
    assert_eq!(0, ab.foo4());

    ab.set_foo1(1);
    assert_eq!([1, 0, 0], ab.0);
    assert_eq!(1, ab.foo1());
    assert_eq!(1, ab.foo2());
    assert_eq!(0, ab.foo3());
    assert_eq!(0, ab.foo4());

    ab.set_foo1(0);
    ab.set_foo2(0xFF);
    assert_eq!([0xFF, 0, 0], ab.0);
    assert_eq!(1, ab.foo1());
    assert_eq!(0xFF, ab.foo2());
    assert_eq!(0x7F, ab.foo3());
    assert_eq!(0x0F, ab.foo4());

    ab.set_foo2(0);
    ab.set_foo3(0xFF);
    assert_eq!([0xFE, 0x1, 0], ab.0);
    assert_eq!(0, ab.foo1());
    assert_eq!(0xFE, ab.foo2());
    assert_eq!(0xFF, ab.foo3());
    assert_eq!(0x1F, ab.foo4());

    ab.set_foo3(0);
    ab.set_foo4(0xFFFF);
    assert_eq!([0xF0, 0xFF, 0x0F], ab.0);
    assert_eq!(0, ab.foo1());
    assert_eq!(0xF0, ab.foo2());
    assert_eq!(0xF8, ab.foo3());
    assert_eq!(0xFFFF, ab.foo4());
}
<|endoftext|>


<commit_before>extern crate split_into;

use split_into::split_into;

#[test]
fn test_split_into_empty() {
    assert_eq!(Vec::from_elem(0,0),       split_into(10,0));
    assert_eq!(vec!(10),                  split_into(10,1));
    assert_eq!(vec!(5,5),                 split_into(10,2));
    assert_eq!(vec!(3,3,4),               split_into(10,3));
    assert_eq!(vec!(2,2,3,3),             split_into(10,4));
    assert_eq!(vec!(2,2,2,2,2),           split_into(10,5));
    assert_eq!(vec!(1,1,2,2,2,2),         split_into(10,6));
    assert_eq!(vec!(1,1,1,1,2,2,2),       split_into(10,7));
    assert_eq!(vec!(1,1,1,1,1,1,2,2),     split_into(10,8));
    assert_eq!(vec!(1,1,1,1,1,1,1,1,2),   split_into(10,9));
    assert_eq!(vec!(1,1,1,1,1,1,1,1,1,1), split_into(10,10));
}
<commit_msg>Rename test fn name<commit_after>extern crate split_into;

use split_into::split_into;

#[test]
fn test_split_into() {
    assert_eq!(Vec::from_elem(0,0),       split_into(10,0));
    assert_eq!(vec!(10),                  split_into(10,1));
    assert_eq!(vec!(5,5),                 split_into(10,2));
    assert_eq!(vec!(3,3,4),               split_into(10,3));
    assert_eq!(vec!(2,2,3,3),             split_into(10,4));
    assert_eq!(vec!(2,2,2,2,2),           split_into(10,5));
    assert_eq!(vec!(1,1,2,2,2,2),         split_into(10,6));
    assert_eq!(vec!(1,1,1,1,2,2,2),       split_into(10,7));
    assert_eq!(vec!(1,1,1,1,1,1,2,2),     split_into(10,8));
    assert_eq!(vec!(1,1,1,1,1,1,1,1,2),   split_into(10,9));
    assert_eq!(vec!(1,1,1,1,1,1,1,1,1,1), split_into(10,10));
}
<|endoftext|>


<commit_before>extern crate mtl;
extern crate libc;

use mtl::sys::{MTLCopyAllDevices,MTLOrigin, MTLOriginMake, MTLClearColorMake};

#[test]
fn it_works() {
    let _origin = MTLOriginMake(50, 21, 11);
    let _color = MTLClearColorMake(50.0, 21.0, 11.0, 100.0);
    let _hi = unsafe { MTLCopyAllDevices() };
}
<commit_msg>Add some proper high level tests<commit_after>extern crate mtl;
extern crate libc;

use mtl::{Device};

#[test]
fn get_device() {
    let device = Device::system_default_device();
    assert!(device.is_ok());
}

#[test]
fn get_device_name() {
    let device = Device::system_default_device().unwrap();
    assert!(!device.name().into_owned().is_empty());
}
<|endoftext|>


<commit_before>extern crate trustines;

mod memory {
    use trustines::memory::Memory;
    #[test]
    fn write() {
        let mut m = Memory::new();
        m.write(0, &[0,1,2]);
        assert_eq!(0,m.read8(0).unwrap());
        assert_eq!(1,m.read8(1).unwrap());
        assert_eq!(2,m.read8(2).unwrap());
        m.write(1, &[3]);
        assert_eq!(0,m.read8(0).unwrap());
        assert_eq!(3,m.read8(1).unwrap());
        assert_eq!(2,m.read8(2).unwrap());
    }

    #[test]
    fn read8_basic() {
        let mut m = Memory::new();
        m.write(0,&[5,10]);
        assert_eq!(5,m.read8(0).unwrap());
        assert_eq!(10,m.read8(1).unwrap());
    }
    #[test]
    fn write8_basic() {
        let mut m = Memory::new();
        m.write8(0,5);
        assert_eq!(5,m.mem[0]);

        m.write8(1,10);
        assert_eq!(5,m.mem[0]);
        assert_eq!(10,m.mem[1]);
    }

    #[test]
    fn read16_basic() {
        let mut m = Memory::new();
        m.write(0,&[2,1,0]);
        assert_eq!(258,m.read16(0).unwrap());
        assert_eq!(1,m.read16(1).unwrap());
    }
    #[test]
    fn write16_basic() {
        let mut m = Memory::new();
        m.write16(0,258);
        assert_eq!(2,m.mem[0]);
        assert_eq!(1,m.mem[1]);
    }
    #[test]
    fn readwrite8() {
        let mut m = Memory::new();
        m.write8(0,5);
        m.write8(1,10);
        assert_eq!(5,m.read8(0).unwrap());
        assert_eq!(10,m.read8(1).unwrap());
    }
    #[test]
    fn readwrite16() {
        let mut m = Memory::new();
        m.write16(0,258);
        m.write16(2,300);
        assert_eq!(258,m.read16(0).unwrap());
        assert_eq!(300,m.read16(2).unwrap());
    }
}

mod address_mode {
    use trustines::cpu;
    use trustines::memory::Memory;

    fn build_executor() -> cpu::CpuExecutor {
        let opcode_info = cpu::opcode::load_from_file("resources/opcodes.csv").unwrap();
        return cpu::CpuExecutor::new(opcode_info.0);
    }
    fn build_memory(instr:u8,index:usize, ops: &[u8]) -> Memory {
        let mut m = Memory::new();
        if ops.len() > 0 {
            m.write(index,ops);
        }
        return m;
    }

    // NOTE: the opcodes specified in build_memory are not being exucuted, so the
    //       opcode class (ADC, ASL, BRK, etc) don't actually matter.  What matters
    //       is the addressing mode (Absolute, AbsoluteX, ZeroPage, etc)
    //

    #[test]
    fn absolute() {
        let mut cpu: CpuState = Default::default();
        let mut m = build_memory(0x6D,0, &[]); //0x6D = ADC Absolute
        let exec = build_executor();
    }
    #[test]
    fn absolute_x() {
        let mut cpu: CpuState = Default::default();
        let mut m = build_memory(0x7D,0, &[]); // 0x7D = ADC AbsoluteX
        let exec = build_executor();
    }
    #[test]
    fn absolute_y() {
        let mut cpu: CpuState = Default::default();
        let mut m = build_memory(0x79,0, &[]);// 0x79 = ADC AbsoluteY
        let exec = build_executor();
    }
    #[test]
    fn accumulator() {
        let mut cpu: CpuState = Default::default();
        let mut m = build_memory(0x0A,0, &[]);// 0x0A = ASL Accumulator
        let exec = build_executor();
    }
    #[test]
    fn immediate() {
        let mut cpu: CpuState = Default::default();
        let mut m = build_memory(0x69,0, &[]);// 0x69 = ADC Immediate
        let exec = build_executor();
    }
    #[test]
    fn implied() {
        let mut cpu: CpuState = Default::default();
        let mut m = build_memory(0x00,0, &[]);// 0x00 = BRK Implied
        let exec = build_executor();
    }
    #[test]
    fn indirect() {
        let mut cpu: CpuState = Default::default();
        let mut m = build_memory(0x6C,0, &[]);// 0x6C = JMP Indirect
        let exec = build_executor();
    }
    #[test]
    fn indexed_indirect() {
        let mut cpu: CpuState = Default::default();
        let mut m = build_memory(0x61,0, &[]);// 0x61 = ADC IndexedIndirect
        let exec = build_executor();
    }
    #[test]
    fn indirect_indexed() {
        let mut cpu: CpuState = Default::default();
        let mut m = build_memory(0x71,0, &[]);// 0x71 = ADC IndirectIndexed
        let exec = build_executor();
    }
    #[test]
    fn relative() {
        let mut cpu: CpuState = Default::default();
        let mut m = build_memory(0x90,0, &[]);// 0x90 = BCC IndirectIndexed
        let exec = build_executor();
    }
    #[test]
    fn zeropage() {
        let mut cpu: CpuState = Default::default();
        let mut m = build_memory(0x65,0, &[]);// 0x65 = ADC IndirectIndexed
        let exec = build_executor();
    }
    #[test]
    fn zeropage_x() {
        let mut cpu: CpuState = Default::default();
        let mut m = build_memory(0x75,0, &[]);// 0x75 = ADC IndirectIndexed
        let exec = build_executor();
    }
    #[test]
    fn zeropage_y() {
        let mut cpu: CpuState = Default::default();
        let mut m = build_memory(0xB6,0, &[]);// 0xB6 = LDX IndirectIndexed
        let exec = build_executor();
    }
}

<commit_msg>rearranged address mode tests by type (non-indexed, indexed, etc)<commit_after>extern crate trustines;

mod memory {
    use trustines::memory::Memory;
    #[test]
    fn write() {
        let mut m = Memory::new();
        m.write(0, &[0,1,2]);
        assert_eq!(0,m.read8(0).unwrap());
        assert_eq!(1,m.read8(1).unwrap());
        assert_eq!(2,m.read8(2).unwrap());
        m.write(1, &[3]);
        assert_eq!(0,m.read8(0).unwrap());
        assert_eq!(3,m.read8(1).unwrap());
        assert_eq!(2,m.read8(2).unwrap());
    }

    #[test]
    fn read8_basic() {
        let mut m = Memory::new();
        m.write(0,&[5,10]);
        assert_eq!(5,m.read8(0).unwrap());
        assert_eq!(10,m.read8(1).unwrap());
    }
    #[test]
    fn write8_basic() {
        let mut m = Memory::new();
        m.write8(0,5);
        assert_eq!(5,m.mem[0]);

        m.write8(1,10);
        assert_eq!(5,m.mem[0]);
        assert_eq!(10,m.mem[1]);
    }

    #[test]
    fn read16_basic() {
        let mut m = Memory::new();
        m.write(0,&[2,1,0]);
        assert_eq!(258,m.read16(0).unwrap());
        assert_eq!(1,m.read16(1).unwrap());
    }
    #[test]
    fn write16_basic() {
        let mut m = Memory::new();
        m.write16(0,258);
        assert_eq!(2,m.mem[0]);
        assert_eq!(1,m.mem[1]);
    }
    #[test]
    fn readwrite8() {
        let mut m = Memory::new();
        m.write8(0,5);
        m.write8(1,10);
        assert_eq!(5,m.read8(0).unwrap());
        assert_eq!(10,m.read8(1).unwrap());
    }
    #[test]
    fn readwrite16() {
        let mut m = Memory::new();
        m.write16(0,258);
        m.write16(2,300);
        assert_eq!(258,m.read16(0).unwrap());
        assert_eq!(300,m.read16(2).unwrap());
    }
}

mod address_mode {
    use trustines::cpu;
    use trustines::memory::Memory;

    fn build_executor() -> cpu::CpuExecutor {
        let opcode_info = cpu::opcode::load_from_file("resources/opcodes.csv").unwrap();
        return cpu::CpuExecutor::new(opcode_info.0);
    }
    fn build_memory(instr:u8,index:usize, ops: &[u8]) -> Memory {
        let mut m = Memory::new();
        if ops.len() > 0 {
            m.write(index,ops);
        }
        return m;
    }

    // NOTE: the opcodes specified in build_memory are not being exucuted, so the
    //       opcode class (ADC, ASL, BRK, etc) don't actually matter.  What matters
    //       is the addressing mode (Absolute, AbsoluteX, ZeroPage, etc)
    //

// ------------------ Non-Indexed, Non-Memory ------------------ //

    #[test]
    fn accumulator() {
        let mut cpu: CpuState = Default::default();
        let mut m = build_memory(0x0A,0, &[]);// 0x0A = ASL Accumulator
        let exec = build_executor();
    }
    #[test]
    fn immediate() {
        let mut cpu: CpuState = Default::default();
        let mut m = build_memory(0x69,0, &[]);// 0x69 = ADC Immediate
        let exec = build_executor();
    }
    #[test]
    fn implied() {
        let mut cpu: CpuState = Default::default();
        let mut m = build_memory(0x00,0, &[]);// 0x00 = BRK Implied
        let exec = build_executor();
    }

// ------------------ Non-Indexed, Memory ------------------ //

    #[test]
    fn absolute() {
        let mut cpu: CpuState = Default::default();
        let mut m = build_memory(0x6D,0, &[]); //0x6D = ADC Absolute
        let exec = build_executor();
    }
    #[test]
    fn indirect() {
        let mut cpu: CpuState = Default::default();
        let mut m = build_memory(0x6C,0, &[]);// 0x6C = JMP Indirect
        let exec = build_executor();
    }
    #[test]
    fn relative() {
        let mut cpu: CpuState = Default::default();
        let mut m = build_memory(0x90,0, &[]);// 0x90 = BCC IndirectIndexed
        let exec = build_executor();
    }
    #[test]
    fn zeropage() {
        let mut cpu: CpuState = Default::default();
        let mut m = build_memory(0x65,0, &[]);// 0x65 = ADC IndirectIndexed
        let exec = build_executor();
    }

// ------------------ Indexed, Memory ------------------ //

    #[test]
    fn absolute_x() {
        let mut cpu: CpuState = Default::default();
        let mut m = build_memory(0x7D,0, &[]); // 0x7D = ADC AbsoluteX
        let exec = build_executor();
    }
    #[test]
    fn absolute_y() {
        let mut cpu: CpuState = Default::default();
        let mut m = build_memory(0x79,0, &[]);// 0x79 = ADC AbsoluteY
        let exec = build_executor();
    }
    #[test]
    fn zeropage_x() {
        let mut cpu: CpuState = Default::default();
        let mut m = build_memory(0x75,0, &[]);// 0x75 = ADC IndirectIndexed
        let exec = build_executor();
    }
    #[test]
    fn zeropage_y() {
        let mut cpu: CpuState = Default::default();
        let mut m = build_memory(0xB6,0, &[]);// 0xB6 = LDX IndirectIndexed
        let exec = build_executor();
    }
    #[test]
    fn indexed_indirect() {
        let mut cpu: CpuState = Default::default();
        let mut m = build_memory(0x61,0, &[]);// 0x61 = ADC IndexedIndirect
        let exec = build_executor();
    }
    #[test]
    fn indirect_indexed() {
        let mut cpu: CpuState = Default::default();
        let mut m = build_memory(0x71,0, &[]);// 0x71 = ADC IndirectIndexed
        let exec = build_executor();
    }

}

<|endoftext|>


<commit_before>extern crate mtl;
extern crate cocoa;

use mtl::{CompileOptions, Device, LanguageVersion, PreprocessorMacroValue, SpecificLanguageVersion};
use mtl::LibraryErrorType;
use mtl::{FromRaw, FromRawError, IntoRaw};
use mtl::sys::{MTLCompileOptions, MTLLanguageVersion};
use cocoa::base::{BOOL, nil};
use cocoa::foundation::NSString;

#[test]
fn get_device() {
    let device = Device::system_default_device();
    assert!(device.is_ok());
}

#[test]
fn get_all_devices() {
    let all_devices = Device::enumerate_all_system_devices();
    assert!(!all_devices.is_empty());
    for device in all_devices {
        assert!(device.is_ok());
    }
}

#[test]
fn get_device_name() {
    let device = Device::system_default_device().unwrap();
    assert!(!device.name().into_owned().is_empty());
}

#[test]
fn set_get_command_queue_label() {
    let mut device = Device::system_default_device().unwrap();
    let mut command_queue = device.new_command_queue().unwrap();

    let dummy_command_queue_name = "foo";
    command_queue.set_label(dummy_command_queue_name);

    assert_eq!(command_queue.get_label().into_owned(),
               dummy_command_queue_name.to_string());
}

#[test]
fn insert_debug_capture_boundary_on_command_queue() {
    let mut device = Device::system_default_device().unwrap();
    let mut command_queue = device.new_command_queue().unwrap();
    command_queue.insert_debug_capture_boundary();

    // if nothing panics/fails here, everything is okay
}

#[test]
fn device_from_to_raw() {
    let device = Device::system_default_device().unwrap();
    let raw = device.into_raw();
    let device = Device::from_raw(raw);
    assert!(device.is_ok());
}

#[test]
fn device_from_wrong_type() {
    let some_string = unsafe { NSString::alloc(nil).init_str("Hello") };
    let device_result = Device::from_raw(some_string);
    match device_result {
        Result::Err(FromRawError::WrongPointerType) => {
            // pass
        }
        _ => assert!(false),
    }
}

#[test]
fn device_from_nullptr() {
    let device_result = Device::from_raw(nil);
    match device_result {
        Result::Err(FromRawError::NilPointer) => {
            // pass
        }
        _ => assert!(false),
    }
}

#[test]
fn compile_opts_creation_is_correct() {
    let mut options = CompileOptions::default();

    let fast_math_enabled = true;
    options.fast_math_enabled = Some(fast_math_enabled);
    options.language_version = LanguageVersion::Specific(SpecificLanguageVersion::Version_1_0);
    options.preprocessor_macros.insert("Foo".into(), PreprocessorMacroValue::Integral(54));
    options.preprocessor_macros.insert("Bar".into(), PreprocessorMacroValue::Floating(32.0));
    options.preprocessor_macros.insert("Baz".into(), PreprocessorMacroValue::String("Hi".into()));

    let native_options = options.mtl_compile_options();

    unsafe {
        assert_eq!(fast_math_enabled as BOOL,
                   native_options.fastMathEnabled());
        assert_eq!(native_options.languageVersion(),
                   MTLLanguageVersion::MTLLanguageVersion1_0);
    }
}

#[test]
fn create_invalid_shader() {
    let mut device = Device::system_default_device().unwrap();
    const BAD_SHADER: &'static str = r"abcdefghijklmnopqrstuvwxyz";
    match device.new_library_with_source(BAD_SHADER, &Default::default()) {
        Ok(_) => panic!("Incorrect result: expected an error"),
        Err(error) => {
            if let LibraryErrorType::SourceError = error.error_type {
                assert!(true);
            } else {
                panic!("Incorrect error type");
            }

        }
    }
}

#[test]
fn device_create_library_with_valid_shader_code_and_get_fn_names() {
    let mut device = Device::system_default_device().unwrap();
    // Shader source taken from http://metalbyexample.com/up-and-running-2/
    const SHADER: &'static str = r"
        using namespace metal;

        struct ColoredVertex
        {
            float4 position [[position]];
            float4 color;
        };

        vertex ColoredVertex vertex_main(constant float4 *position [[buffer(0)]],
                                         constant float4 *color [[buffer(1)]],
                                         uint vid [[vertex_id]])
        {
            ColoredVertex vert;
            vert.position = position[vid];
            vert.color = color[vid];
            return vert;
        }

        fragment float4 fragment_main(ColoredVertex vert [[stage_in]])
        {
            return vert.color;
        }
    ";
    let library = device.new_library_with_source(SHADER, &Default::default()).ok().unwrap();
    let names = library.function_names();
    assert_eq!(names[0], "vertex_main");
    assert_eq!(names[1], "fragment_main");
}
<commit_msg>Format<commit_after>extern crate mtl;
extern crate cocoa;

use mtl::{CompileOptions, Device, LanguageVersion, PreprocessorMacroValue, SpecificLanguageVersion};
use mtl::LibraryErrorType;
use mtl::{FromRaw, FromRawError, IntoRaw};
use mtl::sys::{MTLCompileOptions, MTLLanguageVersion};
use cocoa::base::{BOOL, nil};
use cocoa::foundation::NSString;

#[test]
fn get_device() {
    let device = Device::system_default_device();
    assert!(device.is_ok());
}

#[test]
fn get_all_devices() {
    let all_devices = Device::enumerate_all_system_devices();
    assert!(!all_devices.is_empty());
    for device in all_devices {
        assert!(device.is_ok());
    }
}

#[test]
fn get_device_name() {
    let device = Device::system_default_device().unwrap();
    assert!(!device.name().into_owned().is_empty());
}

#[test]
fn set_get_command_queue_label() {
    let mut device = Device::system_default_device().unwrap();
    let mut command_queue = device.new_command_queue().unwrap();

    let dummy_command_queue_name = "foo";
    command_queue.set_label(dummy_command_queue_name);

    assert_eq!(command_queue.get_label().into_owned(),
               dummy_command_queue_name.to_string());
}

#[test]
fn insert_debug_capture_boundary_on_command_queue() {
    let mut device = Device::system_default_device().unwrap();
    let mut command_queue = device.new_command_queue().unwrap();
    command_queue.insert_debug_capture_boundary();

    // if nothing panics/fails here, everything is okay
}

#[test]
fn device_from_to_raw() {
    let device = Device::system_default_device().unwrap();
    let raw = device.into_raw();
    let device = Device::from_raw(raw);
    assert!(device.is_ok());
}

#[test]
fn device_from_wrong_type() {
    let some_string = unsafe { NSString::alloc(nil).init_str("Hello") };
    let device_result = Device::from_raw(some_string);
    match device_result {
        Result::Err(FromRawError::WrongPointerType) => {
            // pass
        }
        _ => assert!(false),
    }
}

#[test]
fn device_from_nullptr() {
    let device_result = Device::from_raw(nil);
    match device_result {
        Result::Err(FromRawError::NilPointer) => {
            // pass
        }
        _ => assert!(false),
    }
}

#[test]
fn compile_opts_creation_is_correct() {
    let mut options = CompileOptions::default();

    let fast_math_enabled = true;
    options.fast_math_enabled = Some(fast_math_enabled);
    options.language_version = LanguageVersion::Specific(SpecificLanguageVersion::Version_1_0);
    options.preprocessor_macros.insert("Foo".into(), PreprocessorMacroValue::Integral(54));
    options.preprocessor_macros.insert("Bar".into(), PreprocessorMacroValue::Floating(32.0));
    options.preprocessor_macros.insert("Baz".into(), PreprocessorMacroValue::String("Hi".into()));

    let native_options = options.mtl_compile_options();

    unsafe {
        assert_eq!(fast_math_enabled as BOOL, native_options.fastMathEnabled());
        assert_eq!(native_options.languageVersion(),
                   MTLLanguageVersion::MTLLanguageVersion1_0);
    }
}

#[test]
fn create_invalid_shader() {
    let mut device = Device::system_default_device().unwrap();
    const BAD_SHADER: &'static str = r"abcdefghijklmnopqrstuvwxyz";
    match device.new_library_with_source(BAD_SHADER, &Default::default()) {
        Ok(_) => panic!("Incorrect result: expected an error"),
        Err(error) => {
            if let LibraryErrorType::SourceError = error.error_type {
                assert!(true);
            } else {
                panic!("Incorrect error type");
            }
        }
    }
}

#[test]
fn device_create_library_with_valid_shader_code_and_get_fn_names() {
    let mut device = Device::system_default_device().unwrap();
    // Shader source taken from http://metalbyexample.com/up-and-running-2/
    const SHADER: &'static str = r"
        using namespace metal;

        struct ColoredVertex
        {
            float4 position [[position]];
            float4 color;
        };

        vertex ColoredVertex vertex_main(constant float4 *position [[buffer(0)]],
                                         constant float4 *color [[buffer(1)]],
                                         uint vid [[vertex_id]])
        {
            ColoredVertex vert;
            vert.position = position[vid];
            vert.color = color[vid];
            return vert;
        }

        fragment float4 fragment_main(ColoredVertex vert [[stage_in]])
        {
            return vert.color;
        }
    ";
    let library = device.new_library_with_source(SHADER, &Default::default()).ok().unwrap();
    let names = library.function_names();
    assert_eq!(names[0], "vertex_main");
    assert_eq!(names[1], "fragment_main");
}
<|endoftext|>


<commit_before>use crate::utils::get_test_path;
use cargo_tarpaulin::config::{Config, ConfigWrapper, RunType};
use cargo_tarpaulin::launch_tarpaulin;
use cargo_tarpaulin::traces::*;
use clap::App;
use std::env;
use std::time::Duration;

#[cfg(nightly)]
mod doc_coverage;
mod failures;
mod line_coverage;
mod test_types;
mod utils;
mod workspaces;

pub fn check_percentage_with_cli_args(minimum_coverage: f64, has_lines: bool, args: &[String]) {
    let restore_dir = env::current_dir().unwrap();
    let matches = App::new("tarpaulin")
        .args_from_usage(
             "--config [FILE] 'Path to a toml file specifying a list of options this will override any other options set'
             --ignore-config 'Ignore any project config files'
             --debug 'Show debug output - this is used for diagnosing issues with tarpaulin'
             --verbose -v 'Show extra output'
             --root -r [DIR] 'directory'"
        ).get_matches_from(args);

    let configs = ConfigWrapper::from(&matches).0;
    let mut res = TraceMap::new();
    for config in &configs {
        let (t, _) = launch_tarpaulin(&config).unwrap();
        res.merge(&t);
    }
    res.dedup();
    env::set_current_dir(restore_dir).unwrap();
    assert!(
        res.coverage_percentage() >= minimum_coverage,
        "Assertion failed {} >= {}",
        res.coverage_percentage(),
        minimum_coverage
    );
    if has_lines {
        assert!(res.total_coverable() > 0);
    }
}

pub fn check_percentage_with_config(
    project_name: &str,
    minimum_coverage: f64,
    has_lines: bool,
    mut config: Config,
) {
    config.test_timeout = Duration::from_secs(60);
    let restore_dir = env::current_dir().unwrap();
    let test_dir = get_test_path(project_name);
    env::set_current_dir(&test_dir).unwrap();
    config.manifest = test_dir;
    config.manifest.push("Cargo.toml");

    let (res, _) = launch_tarpaulin(&config).unwrap();

    env::set_current_dir(restore_dir).unwrap();
    if has_lines {
        assert!(res.total_coverable() > 0);
        assert!(
            res.coverage_percentage() >= minimum_coverage,
            "Assertion failed {} >= {}",
            res.coverage_percentage(),
            minimum_coverage
        );
    } else {
        assert_eq!(res.total_coverable(), 0);
    }
}

pub fn check_percentage(project_name: &str, minimum_coverage: f64, has_lines: bool) {
    let config = Config::default();
    check_percentage_with_config(project_name, minimum_coverage, has_lines, config);
}

#[test]
fn incorrect_manifest_path() {
    let mut config = Config::default();
    config.manifest.push("__invalid_dir__");
    let launch = launch_tarpaulin(&config);
    assert!(launch.is_err());
}

#[test]
fn proc_macro_link() {
    let mut config = Config::default();
    config.test_timeout = Duration::from_secs(60);
    let test_dir = get_test_path("proc_macro");
    config.manifest = test_dir.join("Cargo.toml");
    assert!(launch_tarpaulin(&config).is_ok());
}

#[test]
fn array_coverage() {
    check_percentage("arrays", 1.0f64, true);
}

#[test]
fn lets_coverage() {
    check_percentage("lets", 1.0f64, true);
}

#[test]
fn struct_expr_coverage() {
    check_percentage("structs", 1.0f64, true);
}

#[test]
fn ifelse_expr_coverage() {
    check_percentage("ifelse", 1.0f64, true);
}

#[test]
fn returns_expr_coverage() {
    check_percentage("returns", 1.0f64, true);
}

#[test]
fn loops_expr_coverage() {
    check_percentage("loops", 1.0f64, true);
}

#[test]
fn loops_assigns_coverage() {
    check_percentage("assigns", 1.0f64, true);
}

#[test]
fn paths_coverage() {
    check_percentage("paths", 1.0f64, true);
}

#[test]
fn futures_coverage() {
    check_percentage("futures", 1.0f64, true);
}

#[test]
fn breaks_expr_coverage() {
    check_percentage("breaks", 1.0f64, true);
}

#[test]
fn continues_expr_coverage() {
    check_percentage("continues", 1.0f64, true);
}

#[test]
fn boxes_coverage() {
    check_percentage("boxes", 1.0f64, true);
}

#[test]
fn method_calls_expr_coverage() {
    check_percentage("method_calls", 1.0f64, true);
}

#[test]
fn config_file_coverage() {
    let test_dir = get_test_path("configs");
    let mut args = vec![
        "tarpaulin".to_string(),
        "--root".to_string(),
        test_dir.display().to_string(),
    ];
    check_percentage_with_cli_args(1.0f64, true, &args);
    args.push("--ignore-config".to_string());
    check_percentage_with_cli_args(0.0f64, true, &args);
}

#[test]
fn match_expr_coverage() {
    check_percentage("matches", 1.0f64, true);
}

#[test]
#[ignore]
fn benchmark_coverage() {
    let test = "benchmark_coverage";
    check_percentage(test, 0.0f64, true);

    let mut config = Config::default();
    config.run_types = vec![RunType::Benchmarks];
    check_percentage_with_config(test, 1.0f64, true, config);
}

#[test]
fn examples_coverage() {
    let test = "example_test";
    check_percentage(test, 0.0f64, true);

    let mut config = Config::default();
    config.run_types = vec![RunType::Examples];
    check_percentage_with_config(test, 1.0f64, true, config);
}

#[test]
fn access_env_var() {
    // This test is mainly to check that expected environment variables are present
    // using `CARGO_BIN_EXE_<name>` to test
    let test = "env_var";
    check_percentage(test, 1.0f64, true);
}

#[test]
fn tarpaulin_attrs() {
    check_percentage("tarpaulin_attrs", 0.0f64, true);
}

#[test]
#[cfg(nightly)]
fn tarpaulin_tool_attr() {
    check_percentage("tool_attr", 0.0f64, false);
}

<commit_msg>cargo fmt<commit_after>use crate::utils::get_test_path;
use cargo_tarpaulin::config::{Config, ConfigWrapper, RunType};
use cargo_tarpaulin::launch_tarpaulin;
use cargo_tarpaulin::traces::*;
use clap::App;
use std::env;
use std::time::Duration;

#[cfg(nightly)]
mod doc_coverage;
mod failures;
mod line_coverage;
mod test_types;
mod utils;
mod workspaces;

pub fn check_percentage_with_cli_args(minimum_coverage: f64, has_lines: bool, args: &[String]) {
    let restore_dir = env::current_dir().unwrap();
    let matches = App::new("tarpaulin")
        .args_from_usage(
             "--config [FILE] 'Path to a toml file specifying a list of options this will override any other options set'
             --ignore-config 'Ignore any project config files'
             --debug 'Show debug output - this is used for diagnosing issues with tarpaulin'
             --verbose -v 'Show extra output'
             --root -r [DIR] 'directory'"
        ).get_matches_from(args);

    let configs = ConfigWrapper::from(&matches).0;
    let mut res = TraceMap::new();
    for config in &configs {
        let (t, _) = launch_tarpaulin(&config).unwrap();
        res.merge(&t);
    }
    res.dedup();
    env::set_current_dir(restore_dir).unwrap();
    assert!(
        res.coverage_percentage() >= minimum_coverage,
        "Assertion failed {} >= {}",
        res.coverage_percentage(),
        minimum_coverage
    );
    if has_lines {
        assert!(res.total_coverable() > 0);
    }
}

pub fn check_percentage_with_config(
    project_name: &str,
    minimum_coverage: f64,
    has_lines: bool,
    mut config: Config,
) {
    config.test_timeout = Duration::from_secs(60);
    let restore_dir = env::current_dir().unwrap();
    let test_dir = get_test_path(project_name);
    env::set_current_dir(&test_dir).unwrap();
    config.manifest = test_dir;
    config.manifest.push("Cargo.toml");

    let (res, _) = launch_tarpaulin(&config).unwrap();

    env::set_current_dir(restore_dir).unwrap();
    if has_lines {
        assert!(res.total_coverable() > 0);
        assert!(
            res.coverage_percentage() >= minimum_coverage,
            "Assertion failed {} >= {}",
            res.coverage_percentage(),
            minimum_coverage
        );
    } else {
        assert_eq!(res.total_coverable(), 0);
    }
}

pub fn check_percentage(project_name: &str, minimum_coverage: f64, has_lines: bool) {
    let config = Config::default();
    check_percentage_with_config(project_name, minimum_coverage, has_lines, config);
}

#[test]
fn incorrect_manifest_path() {
    let mut config = Config::default();
    config.manifest.push("__invalid_dir__");
    let launch = launch_tarpaulin(&config);
    assert!(launch.is_err());
}

#[test]
fn proc_macro_link() {
    let mut config = Config::default();
    config.test_timeout = Duration::from_secs(60);
    let test_dir = get_test_path("proc_macro");
    config.manifest = test_dir.join("Cargo.toml");
    assert!(launch_tarpaulin(&config).is_ok());
}

#[test]
fn array_coverage() {
    check_percentage("arrays", 1.0f64, true);
}

#[test]
fn lets_coverage() {
    check_percentage("lets", 1.0f64, true);
}

#[test]
fn struct_expr_coverage() {
    check_percentage("structs", 1.0f64, true);
}

#[test]
fn ifelse_expr_coverage() {
    check_percentage("ifelse", 1.0f64, true);
}

#[test]
fn returns_expr_coverage() {
    check_percentage("returns", 1.0f64, true);
}

#[test]
fn loops_expr_coverage() {
    check_percentage("loops", 1.0f64, true);
}

#[test]
fn loops_assigns_coverage() {
    check_percentage("assigns", 1.0f64, true);
}

#[test]
fn paths_coverage() {
    check_percentage("paths", 1.0f64, true);
}

#[test]
fn futures_coverage() {
    check_percentage("futures", 1.0f64, true);
}

#[test]
fn breaks_expr_coverage() {
    check_percentage("breaks", 1.0f64, true);
}

#[test]
fn continues_expr_coverage() {
    check_percentage("continues", 1.0f64, true);
}

#[test]
fn boxes_coverage() {
    check_percentage("boxes", 1.0f64, true);
}

#[test]
fn method_calls_expr_coverage() {
    check_percentage("method_calls", 1.0f64, true);
}

#[test]
fn config_file_coverage() {
    let test_dir = get_test_path("configs");
    let mut args = vec![
        "tarpaulin".to_string(),
        "--root".to_string(),
        test_dir.display().to_string(),
    ];
    check_percentage_with_cli_args(1.0f64, true, &args);
    args.push("--ignore-config".to_string());
    check_percentage_with_cli_args(0.0f64, true, &args);
}

#[test]
fn match_expr_coverage() {
    check_percentage("matches", 1.0f64, true);
}

#[test]
#[ignore]
fn benchmark_coverage() {
    let test = "benchmark_coverage";
    check_percentage(test, 0.0f64, true);

    let mut config = Config::default();
    config.run_types = vec![RunType::Benchmarks];
    check_percentage_with_config(test, 1.0f64, true, config);
}

#[test]
fn examples_coverage() {
    let test = "example_test";
    check_percentage(test, 0.0f64, true);

    let mut config = Config::default();
    config.run_types = vec![RunType::Examples];
    check_percentage_with_config(test, 1.0f64, true, config);
}

#[test]
fn access_env_var() {
    // This test is mainly to check that expected environment variables are present
    // using `CARGO_BIN_EXE_<name>` to test
    let test = "env_var";
    check_percentage(test, 1.0f64, true);
}

#[test]
fn tarpaulin_attrs() {
    check_percentage("tarpaulin_attrs", 0.0f64, true);
}

#[test]
#[cfg(nightly)]
fn tarpaulin_tool_attr() {
    check_percentage("tool_attr", 0.0f64, false);
}
<|endoftext|>