<commit_before>/// `message!` implement structure that could be sent in exonum network.
///
/// Each message is a piece of data that is signed by creators key.
/// For now it's required to set service id as `const TYPE`, message id as `const ID`, and
/// message fixed part size as `const SIZE`.
///
/// - service id should be unique inside whole exonum.
/// - message id should be unique inside each service.
///
/// For each field, it's required to set exact position in message.
/// # Usage Example:
/// ```
/// #[macro_use] extern crate exonum;
/// # extern crate serde;
///
/// const MY_SERVICE_ID: u16 = 777;
/// const MY_NEW_MESSAGE_ID: u16 = 1;
///
/// message! {
///     struct SendTwoInteger {
///         const TYPE = MY_NEW_MESSAGE_ID;
///         const ID   = MY_SERVICE_ID;
///         const SIZE = 16;
///
///         field first: u64 [0 => 8]
///         field second: u64 [8 => 16]
///     }
/// }
///
/// # fn main() {
///     let (p, creators_key) = ::exonum::crypto::gen_keypair();
/// #    let stucture = create_message(&creators_key);
/// #    println!("Debug structure = {:?}", stucture);
/// # }
///
/// # fn create_message(creators_key: &::exonum::crypto::SecretKey) -> SendTwoInteger {
///     let first = 1u64;
///     let second = 2u64;
///     SendTwoInteger::new(first, second, creators_key)
/// # }
/// ```
///
/// For additionall reference about data layout see also
/// *[ `encoding` documentation](./encoding/index.html).*
///
/// `message!` internaly use `ident_count!`, be sure to add this macro to namespace.
#[macro_export]
macro_rules! message {
    (
    $(#[$attr:meta])*
    struct $name:ident {
        const TYPE = $extension:expr;
        const ID = $id:expr;
        const SIZE = $body:expr;

        $(
        $(#[$field_attr:meta])*
        field $field_name:ident : $field_type:ty [$from:expr => $to:expr]
        )*
    }) => (
        #[derive(Clone, PartialEq)]
        $(#[$attr])*
        pub struct $name {
            raw: $crate::messages::RawMessage
        }

        impl $crate::messages::Message for $name {
            fn raw(&self) -> &$crate::messages::RawMessage {
                &self.raw
            }
        }

        impl<'a> $crate::encoding::SegmentField<'a> for $name {

            fn item_size() -> $crate::encoding::Offset {
                1
            }

            fn count(&self) -> $crate::encoding::Offset {
                self.raw.len() as $crate::encoding::Offset
            }

            fn extend_buffer(&self, buffer: &mut Vec<u8>) {
                buffer.extend_from_slice(self.raw.as_ref().as_ref())
            }

            unsafe fn from_buffer(buffer: &'a [u8],
                                    from: $crate::encoding::Offset,
                                    count: $crate::encoding::Offset) -> Self {
                let raw_message: $crate::messages::RawMessage =
                                    $crate::encoding::SegmentField::from_buffer(buffer,
                                                                from,
                                                                count);
                $crate::messages::FromRaw::from_raw(raw_message).unwrap()
            }

            fn check_data(buffer: &'a [u8],
                    from: $crate::encoding::CheckedOffset,
                    count: $crate::encoding::CheckedOffset,
                    latest_segment: $crate::encoding::CheckedOffset)
              -> $crate::encoding::Result {
                let latest_segment_origin = <$crate::messages::RawMessage as
                                $crate::encoding::SegmentField>::check_data(buffer,
                                                                from,
                                                                count,
                                                                latest_segment)?;
                // TODO: remove this allication,
                // by allowing creating message from borrowed data
                let raw_message: $crate::messages::RawMessage =
                                    unsafe { $crate::encoding::SegmentField::from_buffer(buffer,
                                                                from.unchecked_offset(),
                                                                count.unchecked_offset())};
                let _: $name = $crate::messages::FromRaw::from_raw(raw_message)?;
                Ok(latest_segment_origin)
            }
        }

        impl $crate::messages::FromRaw for $name {
            fn from_raw(raw: $crate::messages::RawMessage)
                -> Result<$name, $crate::encoding::Error> {

                if raw.len() < $body as usize {
                    return Err($crate::encoding::Error::UnexpectedlyShortPayload {
                        actual_size: raw.len() as $crate::encoding::Offset,
                        minimum_size: $body,
                    });
                }

                let len = <Self>::check_fields(&raw)?;

                if len.unchecked_offset() as usize +
                    $crate::crypto::SIGNATURE_LENGTH as usize != raw.len()  {
                   return Err("Incorrect raw message length.".into())
                }

                Ok($name { raw: raw })
            }
        }
        impl $name {
            #[cfg_attr(feature="cargo-clippy", allow(too_many_arguments))]
            /// Create messsage `$name` and sign it.
            pub fn new($($field_name: $field_type,)*
                       secret_key: &$crate::crypto::SecretKey) -> $name {
                use $crate::messages::{RawMessage, MessageWriter};
                let mut writer = MessageWriter::new($crate::messages::PROTOCOL_MAJOR_VERSION,
                                                    $crate::messages::TEST_NETWORK_ID,
                                                    $extension, $id, $body);
                $(writer.write($field_name, $from, $to);)*
                $name { raw: RawMessage::new(writer.sign(secret_key)) }
            }

            /// Create message `$name` and append existing signature.
            #[cfg_attr(feature="cargo-clippy", allow(too_many_arguments))]
            pub fn new_with_signature($($field_name: $field_type,)*
                       signature: &$crate::crypto::Signature) -> $name {
                use $crate::messages::{RawMessage, MessageWriter};
                let mut writer = MessageWriter::new($crate::messages::PROTOCOL_MAJOR_VERSION,
                                                    $crate::messages::TEST_NETWORK_ID,
                                                    $extension, $id, $body);
                $(writer.write($field_name, $from, $to);)*
                $name { raw: RawMessage::new(writer.append_signature(signature)) }

            }

            fn check_fields(raw_message: &$crate::messages::RawMessage) -> $crate::encoding::Result {
                let latest_segment = (($body + $crate::messages::HEADER_LENGTH)
                                        as $crate::encoding::Offset).into();
                $(
                    let field_from: $crate::encoding::Offset = $from;
                    let field_to: $crate::encoding::Offset = $to;
                    let latest_segment = raw_message.check::<$field_type>(field_from.into(),
                                                    field_to.into(),
                                                    latest_segment)?;
                )*
                Ok(latest_segment)
            }

            $(
            $(#[$field_attr])*
            pub fn $field_name(&self) -> $field_type {
                unsafe{ self.raw.read::<$field_type>($from, $to)}
            })*
        }

        impl ::std::fmt::Debug for $name {
            fn fmt(&self, fmt: &mut ::std::fmt::Formatter)
                -> Result<(), ::std::fmt::Error> {
                fmt.debug_struct(stringify!($name))
                 $(.field(stringify!($field_name), &self.$field_name()))*
                   .finish()
            }
        }

        impl $crate::encoding::serialize::json::ExonumJson for $name {
            fn deserialize_field<B> (value: &$crate::encoding::serialize::json::reexport::Value,
                                        buffer: & mut B,
                                        from: $crate::encoding::Offset,
                                        to: $crate::encoding::Offset )
                -> Result<(), Box<::std::error::Error>>
            where B: $crate::encoding::serialize::WriteBufferWrapper
            {
                use $crate::encoding::serialize::json::ExonumJsonDeserialize;
                // deserialize full field
                let structure = <Self as ExonumJsonDeserialize>::deserialize(value)?;
                // then write it
                buffer.write(from, to, structure);
                Ok(())
            }

            fn serialize_field(&self)
                -> Result<$crate::encoding::serialize::json::reexport::Value,
                            Box<::std::error::Error>>
            {
                use $crate::encoding::serialize::json::reexport::Value;
                use $crate::encoding::serialize::json::reexport::Map;
                let mut body = Map::new();
                $(
                    body.insert(stringify!($field_name).to_string(),
                        self.$field_name().serialize_field()?);
                )*
                let mut structure = Map::new();
                structure.insert("body".to_string(), Value::Object(body));
                structure.insert("signature".to_string(),
                                    self.raw.signature().serialize_field()?);
                structure.insert("message_id".to_string(),
                                    self.raw.message_type().serialize_field()?);
                structure.insert("service_id".to_string(),
                                    self.raw.service_id().serialize_field()?);
                structure.insert("network_id".to_string(),
                                    self.raw.network_id().serialize_field()?);
                structure.insert("protocol_version".to_string(),
                                    self.raw.version().serialize_field()?);
                Ok(Value::Object(structure))
            }
        }

        impl $crate::encoding::serialize::json::ExonumJsonDeserialize for $name {
            fn deserialize(value: &$crate::encoding::serialize::json::reexport::Value)
                -> Result<Self, Box<::std::error::Error>>
            {
                use $crate::encoding::serialize::json::ExonumJson;
                use $crate::encoding::serialize::json::reexport::from_value;
                use $crate::messages::{RawMessage, MessageWriter};

                // if we could deserialize values, try append signature
                let obj = value.as_object().ok_or("Can't cast json as object.")?;

                let body = obj.get("body").ok_or("Can't get body from json.")?;

                let signature = from_value(obj.get("signature")
                                    .ok_or("Can't get signature from json")?.clone())?;
                let message_type = from_value(obj.get("message_id")
                                    .ok_or("Can't get message_type from json")?.clone())?;
                let service_id = from_value(obj.get("service_id")
                                    .ok_or("Can't get service_id from json")?.clone())?;

                let network_id = from_value(obj.get("network_id")
                                    .ok_or("Can't get network_id from json")?.clone())?;
                let protocol_version = from_value(obj.get("protocol_version")
                                        .ok_or("Can't get protocol_version from json")?.clone())?;

                if service_id != $extension {
                    return Err("service_id didn't equal real service_id.".into())
                }

                if message_type != $id {
                    return Err("message_id didn't equal real message_id.".into())
                }

                let mut writer = MessageWriter::new(protocol_version, network_id,
                                                        service_id, message_type, $body);
                let obj = body.as_object().ok_or("Can't cast body as object.")?;
                $(
                    let val = obj.get(stringify!($field_name))
                                    .ok_or("Can't get object from json.")?;
                    <$field_type as ExonumJson>::deserialize_field(val,
                                                                    &mut writer, $from, $to )?;
                )*

                Ok($name { raw: RawMessage::new(writer.append_signature(&signature)) })
            }
        }

        // TODO: Rewrite Deserialize and Serialize implementation
        impl<'de> $crate::encoding::serialize::reexport::Deserialize<'de> for $name {
            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
                where D: $crate::encoding::serialize::reexport::Deserializer<'de>
            {
                use $crate::encoding::serialize::json::reexport::Value;
                use $crate::encoding::serialize::reexport::{DeError, Deserialize};
                let value = <Value as Deserialize>::deserialize(deserializer)?;
                <Self as $crate::encoding::serialize::json::ExonumJsonDeserialize>::deserialize(&value)
                .map_err(|_| D::Error::custom("Can not deserialize value."))
            }
        }

        impl $crate::encoding::serialize::reexport::Serialize for $name {
            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
                where S: $crate::encoding::serialize::reexport::Serializer
           {
               use $crate::encoding::serialize::reexport::SerError;
                use $crate::encoding::serialize::json::ExonumJson;
                self.serialize_field()
                    .map_err(|_| S::Error::custom(
                                concat!("Can not serialize structure: ", stringify!($name))))?
                    .serialize(serializer)
            }
        }

    )
}
<commit_msg>add static methods for `message`<commit_after>/// `message!` implement structure that could be sent in exonum network.
///
/// Each message is a piece of data that is signed by creators key.
/// For now it's required to set service id as `const TYPE`, message id as `const ID`, and
/// message fixed part size as `const SIZE`.
///
/// - service id should be unique inside whole exonum.
/// - message id should be unique inside each service.
///
/// For each field, it's required to set exact position in message.
/// # Usage Example:
/// ```
/// #[macro_use] extern crate exonum;
/// # extern crate serde;
///
/// const MY_SERVICE_ID: u16 = 777;
/// const MY_NEW_MESSAGE_ID: u16 = 1;
///
/// message! {
///     struct SendTwoInteger {
///         const TYPE = MY_NEW_MESSAGE_ID;
///         const ID   = MY_SERVICE_ID;
///         const SIZE = 16;
///
///         field first: u64 [0 => 8]
///         field second: u64 [8 => 16]
///     }
/// }
///
/// # fn main() {
///     let (p, creators_key) = ::exonum::crypto::gen_keypair();
/// #    let stucture = create_message(&creators_key);
/// #    println!("Debug structure = {:?}", stucture);
/// # }
///
/// # fn create_message(creators_key: &::exonum::crypto::SecretKey) -> SendTwoInteger {
///     let first = 1u64;
///     let second = 2u64;
///     SendTwoInteger::new(first, second, creators_key)
/// # }
/// ```
///
/// For additionall reference about data layout see also
/// *[ `encoding` documentation](./encoding/index.html).*
///
/// `message!` internaly use `ident_count!`, be sure to add this macro to namespace.
#[macro_export]
macro_rules! message {
    (
    $(#[$attr:meta])*
    struct $name:ident {
        const TYPE = $extension:expr;
        const ID = $id:expr;
        const SIZE = $body:expr;

        $(
        $(#[$field_attr:meta])*
        field $field_name:ident : $field_type:ty [$from:expr => $to:expr]
        )*
    }) => (
        #[derive(Clone, PartialEq)]
        $(#[$attr])*
        pub struct $name {
            raw: $crate::messages::RawMessage
        }

        impl $crate::messages::Message for $name {
            fn raw(&self) -> &$crate::messages::RawMessage {
                &self.raw
            }
        }

        impl<'a> $crate::encoding::SegmentField<'a> for $name {

            fn item_size() -> $crate::encoding::Offset {
                1
            }

            fn count(&self) -> $crate::encoding::Offset {
                self.raw.len() as $crate::encoding::Offset
            }

            fn extend_buffer(&self, buffer: &mut Vec<u8>) {
                buffer.extend_from_slice(self.raw.as_ref().as_ref())
            }

            unsafe fn from_buffer(buffer: &'a [u8],
                                    from: $crate::encoding::Offset,
                                    count: $crate::encoding::Offset) -> Self {
                let raw_message: $crate::messages::RawMessage =
                                    $crate::encoding::SegmentField::from_buffer(buffer,
                                                                from,
                                                                count);
                $crate::messages::FromRaw::from_raw(raw_message).unwrap()
            }

            fn check_data(buffer: &'a [u8],
                    from: $crate::encoding::CheckedOffset,
                    count: $crate::encoding::CheckedOffset,
                    latest_segment: $crate::encoding::CheckedOffset)
              -> $crate::encoding::Result {
                let latest_segment_origin = <$crate::messages::RawMessage as
                                $crate::encoding::SegmentField>::check_data(buffer,
                                                                from,
                                                                count,
                                                                latest_segment)?;
                // TODO: remove this allication,
                // by allowing creating message from borrowed data
                let raw_message: $crate::messages::RawMessage =
                                    unsafe { $crate::encoding::SegmentField::from_buffer(buffer,
                                                                from.unchecked_offset(),
                                                                count.unchecked_offset())};
                let _: $name = $crate::messages::FromRaw::from_raw(raw_message)?;
                Ok(latest_segment_origin)
            }
        }

        impl $crate::messages::FromRaw for $name {
            fn from_raw(raw: $crate::messages::RawMessage)
                -> Result<$name, $crate::encoding::Error> {

                if raw.len() < $body as usize {
                    return Err($crate::encoding::Error::UnexpectedlyShortPayload {
                        actual_size: raw.len() as $crate::encoding::Offset,
                        minimum_size: $body,
                    });
                }

                let len = <Self>::check_fields(&raw)?;

                if len.unchecked_offset() as usize +
                    $crate::crypto::SIGNATURE_LENGTH as usize != raw.len()  {
                   return Err("Incorrect raw message length.".into())
                }

                Ok($name { raw: raw })
            }
        }
        impl $name {
            #[cfg_attr(feature="cargo-clippy", allow(too_many_arguments))]
            /// Create messsage `$name` and sign it.
            pub fn new($($field_name: $field_type,)*
                       secret_key: &$crate::crypto::SecretKey) -> $name {
                use $crate::messages::{RawMessage, MessageWriter};
                let mut writer = MessageWriter::new($crate::messages::PROTOCOL_MAJOR_VERSION,
                                                    $crate::messages::TEST_NETWORK_ID,
                                                    $extension, $id, $body);
                $(writer.write($field_name, $from, $to);)*
                $name { raw: RawMessage::new(writer.sign(secret_key)) }
            }

            /// Create message `$name` and append existing signature.
            #[cfg_attr(feature="cargo-clippy", allow(too_many_arguments))]
            pub fn new_with_signature($($field_name: $field_type,)*
                       signature: &$crate::crypto::Signature) -> $name {
                use $crate::messages::{RawMessage, MessageWriter};
                let mut writer = MessageWriter::new($crate::messages::PROTOCOL_MAJOR_VERSION,
                                                    $crate::messages::TEST_NETWORK_ID,
                                                    $extension, $id, $body);
                $(writer.write($field_name, $from, $to);)*
                $name { raw: RawMessage::new(writer.append_signature(signature)) }

            }

            fn check_fields(raw_message: &$crate::messages::RawMessage) -> $crate::encoding::Result {
                let latest_segment = (($body + $crate::messages::HEADER_LENGTH)
                                        as $crate::encoding::Offset).into();
                $(
                    let field_from: $crate::encoding::Offset = $from;
                    let field_to: $crate::encoding::Offset = $to;
                    let latest_segment = raw_message.check::<$field_type>(field_from.into(),
                                                    field_to.into(),
                                                    latest_segment)?;
                )*
                Ok(latest_segment)
            }

            /// return `$name`s `message_id` useable for matching.
            pub fn message_id() -> u16 {
                $id
            }

            /// return `$name`s `service_id` useable for matching.
            pub fn service_id() -> u16 {
                $extension
            }

            $(
            $(#[$field_attr])*
            pub fn $field_name(&self) -> $field_type {
                unsafe{ self.raw.read::<$field_type>($from, $to)}
            })*
        }

        impl ::std::fmt::Debug for $name {
            fn fmt(&self, fmt: &mut ::std::fmt::Formatter)
                -> Result<(), ::std::fmt::Error> {
                fmt.debug_struct(stringify!($name))
                 $(.field(stringify!($field_name), &self.$field_name()))*
                   .finish()
            }
        }

        impl $crate::encoding::serialize::json::ExonumJson for $name {
            fn deserialize_field<B> (value: &$crate::encoding::serialize::json::reexport::Value,
                                        buffer: & mut B,
                                        from: $crate::encoding::Offset,
                                        to: $crate::encoding::Offset )
                -> Result<(), Box<::std::error::Error>>
            where B: $crate::encoding::serialize::WriteBufferWrapper
            {
                use $crate::encoding::serialize::json::ExonumJsonDeserialize;
                // deserialize full field
                let structure = <Self as ExonumJsonDeserialize>::deserialize(value)?;
                // then write it
                buffer.write(from, to, structure);
                Ok(())
            }

            fn serialize_field(&self)
                -> Result<$crate::encoding::serialize::json::reexport::Value,
                            Box<::std::error::Error>>
            {
                use $crate::encoding::serialize::json::reexport::Value;
                use $crate::encoding::serialize::json::reexport::Map;
                let mut body = Map::new();
                $(
                    body.insert(stringify!($field_name).to_string(),
                        self.$field_name().serialize_field()?);
                )*
                let mut structure = Map::new();
                structure.insert("body".to_string(), Value::Object(body));
                structure.insert("signature".to_string(),
                                    self.raw.signature().serialize_field()?);
                structure.insert("message_id".to_string(),
                                    self.raw.message_type().serialize_field()?);
                structure.insert("service_id".to_string(),
                                    self.raw.service_id().serialize_field()?);
                structure.insert("network_id".to_string(),
                                    self.raw.network_id().serialize_field()?);
                structure.insert("protocol_version".to_string(),
                                    self.raw.version().serialize_field()?);
                Ok(Value::Object(structure))
            }
        }

        impl $crate::encoding::serialize::json::ExonumJsonDeserialize for $name {
            fn deserialize(value: &$crate::encoding::serialize::json::reexport::Value)
                -> Result<Self, Box<::std::error::Error>>
            {
                use $crate::encoding::serialize::json::ExonumJson;
                use $crate::encoding::serialize::json::reexport::from_value;
                use $crate::messages::{RawMessage, MessageWriter};

                // if we could deserialize values, try append signature
                let obj = value.as_object().ok_or("Can't cast json as object.")?;

                let body = obj.get("body").ok_or("Can't get body from json.")?;

                let signature = from_value(obj.get("signature")
                                    .ok_or("Can't get signature from json")?.clone())?;
                let message_type = from_value(obj.get("message_id")
                                    .ok_or("Can't get message_type from json")?.clone())?;
                let service_id = from_value(obj.get("service_id")
                                    .ok_or("Can't get service_id from json")?.clone())?;

                let network_id = from_value(obj.get("network_id")
                                    .ok_or("Can't get network_id from json")?.clone())?;
                let protocol_version = from_value(obj.get("protocol_version")
                                        .ok_or("Can't get protocol_version from json")?.clone())?;

                if service_id != $extension {
                    return Err("service_id didn't equal real service_id.".into())
                }

                if message_type != $id {
                    return Err("message_id didn't equal real message_id.".into())
                }

                let mut writer = MessageWriter::new(protocol_version, network_id,
                                                        service_id, message_type, $body);
                let obj = body.as_object().ok_or("Can't cast body as object.")?;
                $(
                    let val = obj.get(stringify!($field_name))
                                    .ok_or("Can't get object from json.")?;
                    <$field_type as ExonumJson>::deserialize_field(val,
                                                                    &mut writer, $from, $to )?;
                )*

                Ok($name { raw: RawMessage::new(writer.append_signature(&signature)) })
            }
        }

        // TODO: Rewrite Deserialize and Serialize implementation
        impl<'de> $crate::encoding::serialize::reexport::Deserialize<'de> for $name {
            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
                where D: $crate::encoding::serialize::reexport::Deserializer<'de>
            {
                use $crate::encoding::serialize::json::reexport::Value;
                use $crate::encoding::serialize::reexport::{DeError, Deserialize};
                let value = <Value as Deserialize>::deserialize(deserializer)?;
                <Self as $crate::encoding::serialize::json::ExonumJsonDeserialize>::deserialize(&value)
                .map_err(|_| D::Error::custom("Can not deserialize value."))
            }
        }

        impl $crate::encoding::serialize::reexport::Serialize for $name {
            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
                where S: $crate::encoding::serialize::reexport::Serializer
           {
               use $crate::encoding::serialize::reexport::SerError;
                use $crate::encoding::serialize::json::ExonumJson;
                self.serialize_field()
                    .map_err(|_| S::Error::custom(
                                concat!("Can not serialize structure: ", stringify!($name))))?
                    .serialize(serializer)
            }
        }

    )
}
<|endoftext|>


<commit_before>use matrix::{Scalar,Mat,Subcomputation,ResizableBuffer};
use thread_comm::ThreadInfo;
use composables::{GemmNode,AlgorithmStep};
use std::marker::PhantomData;

// TODO: remove on non-lexical lifetimes?
// Used to prevent rather understandable borrowcheck complaints on resizing
struct MetadataOnlyMatrix<T: Scalar> {
    iter_height: usize,
    iter_width: usize,
    logical_w_padding: usize,
    logical_h_padding: usize,
    width: usize,
    height: usize,
    _t: PhantomData<T>,
}

impl<T: Scalar> MetadataOnlyMatrix<T> {
    pub fn new(other: &Mat<T>) -> Self{
        MetadataOnlyMatrix {
            iter_width: other.iter_width(),
            iter_height: other.iter_height(),
            logical_w_padding: other.logical_w_padding(),
            logical_h_padding: other.logical_h_padding(),
            width: other.width(),
            height: other.height(),
            _t: PhantomData,
        }
    }
}

impl<T: Scalar> Mat<T> for MetadataOnlyMatrix<T> {
    // These set outputs of C
    #[inline(always)]
    fn get(&self, _y: usize, _x: usize) -> T { unimplemented!(); }
    #[inline(always)]
    fn set(&mut self, _y: usize, _x: usize, _alpha: T) { unimplemented!(); }

    #[inline(always)]
    fn iter_height(&self) -> usize {
        self.iter_height
    }
    #[inline(always)]
    fn iter_width(&self) -> usize {
        self.iter_width
    }
    #[inline(always)]
    fn logical_h_padding(&self) -> usize {
        self.logical_h_padding
    }
    #[inline(always)]
    fn logical_w_padding(&self) -> usize {
        self.logical_w_padding
    }
    #[inline(always)]
    fn height(&self) -> usize {
        self.height
    }
    #[inline(always)]
    fn width(&self) -> usize {
        self.width
    }

    #[inline(always)]
    fn set_scalar(&mut self, _alpha: T) { unimplemented!(); }
    #[inline(always)]
    fn get_scalar(&self) -> T { unimplemented!(); }
    fn push_y_split(&mut self, _start: usize, _end: usize) { unimplemented!(); }
    fn push_x_split(&mut self, _start: usize, _end: usize) { unimplemented!(); }
    #[inline(always)]
    fn pop_y_split(&mut self) { unimplemented!(); }
    #[inline(always)]
    fn pop_x_split(&mut self) { unimplemented!(); }
    fn push_y_view(&mut self, _blksz: usize) -> usize { unimplemented!(); }
    fn push_x_view(&mut self, _blksz: usize) -> usize { unimplemented!(); }
    #[inline(always)]
    fn pop_y_view(&mut self) { unimplemented!(); }
    #[inline(always)]
    fn pop_x_view(&mut self) { unimplemented!(); }
    fn slide_y_view_to(&mut self, _y: usize, _blksz: usize) { unimplemented!(); }
    fn slide_x_view_to(&mut self, _x: usize, _blksz: usize) { unimplemented!(); }
    #[inline(always)]
    unsafe fn make_alias(&self) -> Self { unimplemented!(); }
    #[inline(always)]
    unsafe fn send_alias(&mut self, thr: &ThreadInfo<T>) { unimplemented!(); }
}

pub struct ForceA<T: Scalar, AiT: Mat<T>, BiT: Mat<T>, CiT: Mat<T>,
                  Bt: Mat<T>, Ct: Mat<T>,
                  Sc: GemmNode<T, AiT, BiT, CiT>,
                  S: GemmNode<T, CiT, Bt, Ct>> {
    child: S,
    subalgorithm: Sc,
    _t: PhantomData<T>,
    _ait: PhantomData<AiT>,
    _bit: PhantomData<BiT>,
    _cit: PhantomData<CiT>,
    _bt: PhantomData<Bt>,
    _ct: PhantomData<Ct>,
}

impl<T: Scalar, AiT: Mat<T>, BiT: Mat<T>, CiT: Mat<T>, Bt: Mat<T>, Ct: Mat<T>,
     Sc: GemmNode<T, AiT, BiT, CiT>, S: GemmNode<T, CiT, Bt, Ct>>
    ForceA<T, AiT, BiT, CiT, Bt, Ct, Sc, S> {
}

impl<T: Scalar, AiT: Mat<T>, BiT: Mat<T>, CiT: Mat<T>,
     Bt: Mat<T>, Ct: Mat<T>,
     Sc: GemmNode<T, AiT, BiT, CiT>,
     S: GemmNode<T, CiT, Bt, Ct>>
    GemmNode<T, Subcomputation<T, AiT, BiT, CiT>, Bt, Ct>
    for ForceA<T, AiT, BiT, CiT, Bt, Ct, Sc, S> {
    #[inline(always)]
    default unsafe fn run(&mut self, a: &mut Subcomputation<T, AiT, BiT, CiT>,
                          b: &mut Bt, c: &mut Ct, thr: &ThreadInfo<T>) -> () {
        let beta_save = a.c.get_scalar();
        a.c.set_scalar(T::zero());
        self.subalgorithm.run(&mut a.a, &mut a.b, &mut a.c, thr);
        a.c.set_scalar(beta_save);
        let new_a = &mut a.c;
        self.child.run(new_a, b, c, thr);
    }

    fn new() -> Self {
        ForceA {child: S::new(), subalgorithm: Sc::new(),
                _t: PhantomData, _ait: PhantomData,
                _bit: PhantomData, _cit: PhantomData,
                _bt: PhantomData, _ct: PhantomData }
    }

    fn hierarchy_description() -> Vec<AlgorithmStep> {
        S::hierarchy_description()
    }
}

impl<T: Scalar, AiT: Mat<T>, BiT: Mat<T>, CiT: Mat<T>,
     Bt: Mat<T>, Ct: Mat<T>,
     Sc: GemmNode<T, AiT, BiT, CiT>,
     S: GemmNode<T, CiT, Bt, Ct>>
    GemmNode<T, Subcomputation<T, AiT, BiT, CiT>, Bt, Ct>
    for ForceA<T, AiT, BiT, CiT, Bt, Ct, Sc, S>
    where CiT: ResizableBuffer<T> {
    #[inline(always)]
    unsafe fn run(&mut self, a: &mut Subcomputation<T, AiT, BiT, CiT>,
                  b: &mut Bt, c: &mut Ct, thr: &ThreadInfo<T>) -> () {
        let dummy_algo_desc: [AlgorithmStep; 0] = [];
        let y_marker = AlgorithmStep::K{bsz: 0};
        let x_marker = AlgorithmStep::N{bsz: 0};
        // Here, a has height from a.a and width from a.b
        let metadata = MetadataOnlyMatrix::new(a);
        let capacity_for_cit = CiT:: capacity_for(&metadata, y_marker, x_marker, &dummy_algo_desc);

        //Check if we need to resize packing buffer
        if a.c.capacity() < capacity_for_cit {
            if thr.thread_id() == 0 {
                a.c.aquire_buffer_for(capacity_for_cit);
            }
            else {
                a.c.set_capacity(capacity_for_cit);
            }
            //self.b_pack.send_alias(thr);
        }

        //Logically resize the output matrix
        a.c.resize_to(&metadata, y_marker, x_marker, &dummy_algo_desc);

        let beta_save = a.c.get_scalar();
        a.c.set_scalar(T::zero());

        self.subalgorithm.run(&mut a.a, &mut a.b, &mut a.c, thr);
        a.c.set_scalar(beta_save);

        let new_a = &mut a.c;
        self.child.run(new_a, b, c, thr);
    }
}

pub struct ForceB<T: Scalar, At: Mat<T>,
                  AiT: Mat<T>, BiT: Mat<T>, CiT: Mat<T>,
                  Ct: Mat<T>,
                  Sc: GemmNode<T, AiT, BiT, CiT>,
                  S: GemmNode<T, At, CiT, Ct>> {
    child: S,
    subalgorithm: Sc,
    _t: PhantomData<T>,
    _at: PhantomData<At>,
    _ait: PhantomData<AiT>,
    _bit: PhantomData<BiT>,
    _cit: PhantomData<CiT>,
    _ct: PhantomData<Ct>,
}

impl<T: Scalar, At: Mat<T>,
     AiT: Mat<T>, BiT: Mat<T>, CiT: Mat<T>, Ct: Mat<T>,
     Sc: GemmNode<T, AiT, BiT, CiT>, S: GemmNode<T, At, CiT, Ct>>
    ForceB<T, At, AiT, BiT, CiT, Ct, Sc, S> {
}

impl<T: Scalar, At: Mat<T>,
     AiT: Mat<T>, BiT: Mat<T>, CiT: Mat<T>,
     Ct: Mat<T>,
     Sc: GemmNode<T, AiT, BiT, CiT>,
     S: GemmNode<T, At, CiT, Ct>>
    GemmNode<T, At, Subcomputation<T, AiT, BiT, CiT>, Ct>
    for ForceB<T, At, AiT, BiT, CiT, Ct, Sc, S> {
    #[inline(always)]
    default unsafe fn run(&mut self, a: &mut At,
                  b: &mut Subcomputation<T, AiT, BiT, CiT>,
                  c: &mut Ct, thr: &ThreadInfo<T>) -> () {
        let beta_save = b.c.get_scalar();
        b.c.set_scalar(T::zero());
        self.subalgorithm.run(&mut b.a, &mut b.b, &mut b.c, thr);
        b.c.set_scalar(beta_save);
        let new_b = &mut b.c;
        self.child.run(a, new_b, c, thr);
    }

    fn new() -> Self {
        ForceB {child: S::new(), subalgorithm: Sc::new(),
                _t: PhantomData, _ait: PhantomData,
                _bit: PhantomData, _cit: PhantomData,
                _at: PhantomData, _ct: PhantomData }
    }

    fn hierarchy_description() -> Vec<AlgorithmStep> {
        S::hierarchy_description()
    }
}

impl<T: Scalar, At: Mat<T>,
     AiT: Mat<T>, BiT: Mat<T>, CiT: Mat<T>,
     Ct: Mat<T>,
     Sc: GemmNode<T, AiT, BiT, CiT>,
     S: GemmNode<T, At, CiT, Ct>>
    GemmNode<T, At, Subcomputation<T, AiT, BiT, CiT>, Ct>
    for ForceB<T, At, AiT, BiT, CiT, Ct, Sc, S>
    where CiT: ResizableBuffer<T> {
    #[inline(always)]
    unsafe fn run(&mut self, a: &mut At,
                  b: &mut Subcomputation<T, AiT, BiT, CiT>,
                  c: &mut Ct, thr: &ThreadInfo<T>) -> () {
        let dummy_algo_desc: [AlgorithmStep; 0] = [];
        let y_marker = AlgorithmStep::K{bsz: 0};
        let x_marker = AlgorithmStep::N{bsz: 0};
        // Here, b has height from b.a and width from b.b
        let metadata = MetadataOnlyMatrix::new(b);
        let capacity_for_cit = CiT:: capacity_for(&metadata, y_marker, x_marker, &dummy_algo_desc);

        //Check if we need to resize packing buffer
        if b.c.capacity() < capacity_for_cit {
            if thr.thread_id() == 0 {
                b.c.aquire_buffer_for(capacity_for_cit);
            }
            else {
                b.c.set_capacity(capacity_for_cit);
            }
            //self.b_pack.send_alias(thr);
        }

        //Logically resize the output matrix
        b.c.resize_to(&metadata, y_marker, x_marker, &dummy_algo_desc);

        let beta_save = b.c.get_scalar();
        b.c.set_scalar(T::zero());

        self.subalgorithm.run(&mut b.a, &mut b.b, &mut b.c, thr);
        b.c.set_scalar(beta_save);

        let new_b = &mut b.c;
        self.child.run(a, new_b, c, thr);
    }
}
<commit_msg>Remove some panics on metadata matrix for codegen improvement, hopefully this doesn't bite anyone in the tail later<commit_after>use matrix::{Scalar,Mat,Subcomputation,ResizableBuffer};
use thread_comm::ThreadInfo;
use composables::{GemmNode,AlgorithmStep};
use std::marker::PhantomData;

// TODO: remove on non-lexical lifetimes?
// Used to prevent rather understandable borrowcheck complaints on resizing
struct MetadataOnlyMatrix<T: Scalar> {
    iter_height: usize,
    iter_width: usize,
    logical_w_padding: usize,
    logical_h_padding: usize,
    width: usize,
    height: usize,
    _t: PhantomData<T>,
}

impl<T: Scalar> MetadataOnlyMatrix<T> {
    pub fn new(other: &Mat<T>) -> Self{
        MetadataOnlyMatrix {
            iter_width: other.iter_width(),
            iter_height: other.iter_height(),
            logical_w_padding: other.logical_w_padding(),
            logical_h_padding: other.logical_h_padding(),
            width: other.width(),
            height: other.height(),
            _t: PhantomData,
        }
    }
}

impl<T: Scalar> Mat<T> for MetadataOnlyMatrix<T> {
    #[inline(always)]
    fn get(&self, _y: usize, _x: usize) -> T { T::zero() }
    #[inline(always)]
    fn set(&mut self, _y: usize, _x: usize, _alpha: T) { }

    #[inline(always)]
    fn iter_height(&self) -> usize {
        self.iter_height
    }
    #[inline(always)]
    fn iter_width(&self) -> usize {
        self.iter_width
    }
    #[inline(always)]
    fn logical_h_padding(&self) -> usize {
        self.logical_h_padding
    }
    #[inline(always)]
    fn logical_w_padding(&self) -> usize {
        self.logical_w_padding
    }
    #[inline(always)]
    fn height(&self) -> usize {
        self.height
    }
    #[inline(always)]
    fn width(&self) -> usize {
        self.width
    }

    #[inline(always)]
    fn set_scalar(&mut self, _alpha: T) { }
    #[inline(always)]
    fn get_scalar(&self) -> T { T::zero() }
    fn push_y_split(&mut self, _start: usize, _end: usize) { }
    fn push_x_split(&mut self, _start: usize, _end: usize) { }
    #[inline(always)]
    fn pop_y_split(&mut self) { }
    #[inline(always)]
    fn pop_x_split(&mut self) { }
    fn push_y_view(&mut self, _blksz: usize) -> usize { 0 }
    fn push_x_view(&mut self, _blksz: usize) -> usize { 0 }
    #[inline(always)]
    fn pop_y_view(&mut self) { }
    #[inline(always)]
    fn pop_x_view(&mut self) { }
    fn slide_y_view_to(&mut self, _y: usize, _blksz: usize) { }
    fn slide_x_view_to(&mut self, _x: usize, _blksz: usize) {}
    #[inline(always)]
    unsafe fn make_alias(&self) -> Self { unimplemented!(); }
    #[inline(always)]
    unsafe fn send_alias(&mut self, thr: &ThreadInfo<T>) { unimplemented!(); }
}

pub struct ForceA<T: Scalar, AiT: Mat<T>, BiT: Mat<T>, CiT: Mat<T>,
                  Bt: Mat<T>, Ct: Mat<T>,
                  Sc: GemmNode<T, AiT, BiT, CiT>,
                  S: GemmNode<T, CiT, Bt, Ct>> {
    child: S,
    subalgorithm: Sc,
    _t: PhantomData<T>,
    _ait: PhantomData<AiT>,
    _bit: PhantomData<BiT>,
    _cit: PhantomData<CiT>,
    _bt: PhantomData<Bt>,
    _ct: PhantomData<Ct>,
}

impl<T: Scalar, AiT: Mat<T>, BiT: Mat<T>, CiT: Mat<T>, Bt: Mat<T>, Ct: Mat<T>,
     Sc: GemmNode<T, AiT, BiT, CiT>, S: GemmNode<T, CiT, Bt, Ct>>
    ForceA<T, AiT, BiT, CiT, Bt, Ct, Sc, S> {
}

impl<T: Scalar, AiT: Mat<T>, BiT: Mat<T>, CiT: Mat<T>,
     Bt: Mat<T>, Ct: Mat<T>,
     Sc: GemmNode<T, AiT, BiT, CiT>,
     S: GemmNode<T, CiT, Bt, Ct>>
    GemmNode<T, Subcomputation<T, AiT, BiT, CiT>, Bt, Ct>
    for ForceA<T, AiT, BiT, CiT, Bt, Ct, Sc, S> {
    #[inline(always)]
    default unsafe fn run(&mut self, a: &mut Subcomputation<T, AiT, BiT, CiT>,
                          b: &mut Bt, c: &mut Ct, thr: &ThreadInfo<T>) -> () {
        let beta_save = a.c.get_scalar();
        a.c.set_scalar(T::zero());
        self.subalgorithm.run(&mut a.a, &mut a.b, &mut a.c, thr);
        a.c.set_scalar(beta_save);
        let new_a = &mut a.c;
        self.child.run(new_a, b, c, thr);
    }

    fn new() -> Self {
        ForceA {child: S::new(), subalgorithm: Sc::new(),
                _t: PhantomData, _ait: PhantomData,
                _bit: PhantomData, _cit: PhantomData,
                _bt: PhantomData, _ct: PhantomData }
    }

    fn hierarchy_description() -> Vec<AlgorithmStep> {
        S::hierarchy_description()
    }
}

impl<T: Scalar, AiT: Mat<T>, BiT: Mat<T>, CiT: Mat<T>,
     Bt: Mat<T>, Ct: Mat<T>,
     Sc: GemmNode<T, AiT, BiT, CiT>,
     S: GemmNode<T, CiT, Bt, Ct>>
    GemmNode<T, Subcomputation<T, AiT, BiT, CiT>, Bt, Ct>
    for ForceA<T, AiT, BiT, CiT, Bt, Ct, Sc, S>
    where CiT: ResizableBuffer<T> {
    #[inline(always)]
    unsafe fn run(&mut self, a: &mut Subcomputation<T, AiT, BiT, CiT>,
                  b: &mut Bt, c: &mut Ct, thr: &ThreadInfo<T>) -> () {
        let dummy_algo_desc: [AlgorithmStep; 0] = [];
        let y_marker = AlgorithmStep::K{bsz: 0};
        let x_marker = AlgorithmStep::N{bsz: 0};
        // Here, a has height from a.a and width from a.b
        let metadata = MetadataOnlyMatrix::new(a);
        let capacity_for_cit = CiT:: capacity_for(&metadata, y_marker, x_marker, &dummy_algo_desc);

        //Check if we need to resize packing buffer
        if a.c.capacity() < capacity_for_cit {
            if thr.thread_id() == 0 {
                a.c.aquire_buffer_for(capacity_for_cit);
            }
            else {
                a.c.set_capacity(capacity_for_cit);
            }
            //self.b_pack.send_alias(thr);
        }

        //Logically resize the output matrix
        a.c.resize_to(&metadata, y_marker, x_marker, &dummy_algo_desc);

        let beta_save = a.c.get_scalar();
        a.c.set_scalar(T::zero());

        self.subalgorithm.run(&mut a.a, &mut a.b, &mut a.c, thr);
        a.c.set_scalar(beta_save);

        let new_a = &mut a.c;
        self.child.run(new_a, b, c, thr);
    }
}

pub struct ForceB<T: Scalar, At: Mat<T>,
                  AiT: Mat<T>, BiT: Mat<T>, CiT: Mat<T>,
                  Ct: Mat<T>,
                  Sc: GemmNode<T, AiT, BiT, CiT>,
                  S: GemmNode<T, At, CiT, Ct>> {
    child: S,
    subalgorithm: Sc,
    _t: PhantomData<T>,
    _at: PhantomData<At>,
    _ait: PhantomData<AiT>,
    _bit: PhantomData<BiT>,
    _cit: PhantomData<CiT>,
    _ct: PhantomData<Ct>,
}

impl<T: Scalar, At: Mat<T>,
     AiT: Mat<T>, BiT: Mat<T>, CiT: Mat<T>, Ct: Mat<T>,
     Sc: GemmNode<T, AiT, BiT, CiT>, S: GemmNode<T, At, CiT, Ct>>
    ForceB<T, At, AiT, BiT, CiT, Ct, Sc, S> {
}

impl<T: Scalar, At: Mat<T>,
     AiT: Mat<T>, BiT: Mat<T>, CiT: Mat<T>,
     Ct: Mat<T>,
     Sc: GemmNode<T, AiT, BiT, CiT>,
     S: GemmNode<T, At, CiT, Ct>>
    GemmNode<T, At, Subcomputation<T, AiT, BiT, CiT>, Ct>
    for ForceB<T, At, AiT, BiT, CiT, Ct, Sc, S> {
    #[inline(always)]
    default unsafe fn run(&mut self, a: &mut At,
                  b: &mut Subcomputation<T, AiT, BiT, CiT>,
                  c: &mut Ct, thr: &ThreadInfo<T>) -> () {
        let beta_save = b.c.get_scalar();
        b.c.set_scalar(T::zero());
        self.subalgorithm.run(&mut b.a, &mut b.b, &mut b.c, thr);
        b.c.set_scalar(beta_save);
        let new_b = &mut b.c;
        self.child.run(a, new_b, c, thr);
    }

    fn new() -> Self {
        ForceB {child: S::new(), subalgorithm: Sc::new(),
                _t: PhantomData, _ait: PhantomData,
                _bit: PhantomData, _cit: PhantomData,
                _at: PhantomData, _ct: PhantomData }
    }

    fn hierarchy_description() -> Vec<AlgorithmStep> {
        S::hierarchy_description()
    }
}

impl<T: Scalar, At: Mat<T>,
     AiT: Mat<T>, BiT: Mat<T>, CiT: Mat<T>,
     Ct: Mat<T>,
     Sc: GemmNode<T, AiT, BiT, CiT>,
     S: GemmNode<T, At, CiT, Ct>>
    GemmNode<T, At, Subcomputation<T, AiT, BiT, CiT>, Ct>
    for ForceB<T, At, AiT, BiT, CiT, Ct, Sc, S>
    where CiT: ResizableBuffer<T> {
    #[inline(always)]
    unsafe fn run(&mut self, a: &mut At,
                  b: &mut Subcomputation<T, AiT, BiT, CiT>,
                  c: &mut Ct, thr: &ThreadInfo<T>) -> () {
        let dummy_algo_desc: [AlgorithmStep; 0] = [];
        let y_marker = AlgorithmStep::K{bsz: 0};
        let x_marker = AlgorithmStep::N{bsz: 0};
        // Here, b has height from b.a and width from b.b
        let metadata = MetadataOnlyMatrix::new(b);
        let capacity_for_cit = CiT:: capacity_for(&metadata, y_marker, x_marker, &dummy_algo_desc);

        //Check if we need to resize packing buffer
        if b.c.capacity() < capacity_for_cit {
            if thr.thread_id() == 0 {
                b.c.aquire_buffer_for(capacity_for_cit);
            }
            else {
                b.c.set_capacity(capacity_for_cit);
            }
            //self.b_pack.send_alias(thr);
        }

        //Logically resize the output matrix
        b.c.resize_to(&metadata, y_marker, x_marker, &dummy_algo_desc);

        let beta_save = b.c.get_scalar();
        b.c.set_scalar(T::zero());

        self.subalgorithm.run(&mut b.a, &mut b.b, &mut b.c, thr);
        b.c.set_scalar(beta_save);

        let new_b = &mut b.c;
        self.child.run(a, new_b, c, thr);
    }
}
<|endoftext|>


<commit_before>use rocket_contrib::Json;
use rocket::request::FromParam;
use rocket::http::RawStr;
use ldap_hook::user::LdapUser;
use ldap_hook::config::LdapConfig;
use ldap_hook::ldap_search;

#[derive(PartialEq, Eq)]
pub enum LdapQueryType {
	Nick,
	UID,
}

impl<'a> FromParam<'a> for LdapQueryType {
	type Error = &'a RawStr;
	fn from_param(param: &'a RawStr) -> Result<Self, Self::Error> {
		if param == "nick" {
			Ok(LdapQueryType::Nick)
		} else if param == "uid" {
			Ok(LdapQueryType::UID)
		} else {
			Err(param)
		}
	}
}

// Dummy endpoints so that the front-end won't complain
#[get("/search/<query_type>")]
pub fn empty_search(query_type: LdapQueryType) -> Json<Vec<String>> { Json(vec![]) }

#[get("/search/<query_type>/<query>")]
pub fn search(query_type: LdapQueryType, query: String) -> Json<Vec<LdapUser>> {
	let id_list: Vec<String> = query.split(",").map(|s| s.to_string()).collect();

	let mut result_list: Vec<LdapUser> = vec![];

	// TODO: Load the config somewhere more sensible
	let ldap_config = match LdapConfig::load("config.toml") {
		Ok(ldap_config) => ldap_config,
		Err(msg) => {
			panic!("Could not load config.toml: {}", msg);
		}
	};

	for id in &id_list{
		let filter = match query_type {
			LdapQueryType::UID  => format!("(uid={})", id),
			LdapQueryType::Nick => format!("(nickname=*{}*)", id), // Basic fuzzy search when querying by nicknames
		};
		let res = ldap_search(&ldap_config, filter.as_str());

		match res.ok() {
			None => { break; }
			Some(list) => {
				for entry in list {
					if !result_list.contains(&entry) {
						result_list.push(entry)
					}
				}
			}
		}
	}

	Json(result_list)
}
<commit_msg>Sort results in backend<commit_after>use rocket_contrib::Json;
use rocket::request::FromParam;
use rocket::http::RawStr;
use ldap_hook::user::LdapUser;
use ldap_hook::config::LdapConfig;
use ldap_hook::ldap_search;

#[derive(PartialEq, Eq)]
pub enum LdapQueryType {
	Nick,
	UID,
}

impl<'a> FromParam<'a> for LdapQueryType {
	type Error = &'a RawStr;
	fn from_param(param: &'a RawStr) -> Result<Self, Self::Error> {
		if param == "nick" {
			Ok(LdapQueryType::Nick)
		} else if param == "uid" {
			Ok(LdapQueryType::UID)
		} else {
			Err(param)
		}
	}
}

// Dummy endpoints so that the front-end won't complain
#[get("/search/<query_type>")]
pub fn empty_search(query_type: LdapQueryType) -> Json<Vec<String>> { Json(vec![]) }

#[get("/search/<query_type>/<query>")]
pub fn search(query_type: LdapQueryType, query: String) -> Json<Vec<LdapUser>> {
	let id_list: Vec<String> = query.split(",").map(|s| s.to_string()).collect();

	let mut result_list: Vec<LdapUser> = vec![];

	// TODO: Load the config somewhere more sensible
	let ldap_config = match LdapConfig::load("config.toml") {
		Ok(ldap_config) => ldap_config,
		Err(msg) => {
			panic!("Could not load config.toml: {}", msg);
		}
	};

	for id in &id_list{
		let filter = match query_type {
			LdapQueryType::UID  => format!("(uid={})", id),
			LdapQueryType::Nick => format!("(nickname=*{}*)", id), // Basic fuzzy search when querying by nicknames
		};
		let res = ldap_search(&ldap_config, filter.as_str());

		match res.ok() {
			None => { break; }
			Some(list) => {
				for entry in list {
					if !result_list.contains(&entry) {
						result_list.push(entry)
					}
				}
			}
		}
	}

	result_list.sort_by(|a, b| match query_type {
		LdapQueryType::UID  => a.uid .cmp(&b.uid ),
		LdapQueryType::Nick => a.nick.cmp(&b.nick),
	});

	Json(result_list)
}
<|endoftext|>


<commit_before>use crate::utils::{match_qpath, paths, snippet, span_lint_and_sugg};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::*;
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};

declare_clippy_lint! {
    /// **What it does:** Checks usage of `std::fs::create_dir` and suggest using `std::fs::create_dir_all` instead.
    ///
    /// **Why is this bad?** Sometimes `std::fs::crate_dir` is mistakenly chosen over `std::fs::create_dir_all`.
    ///
    /// **Known problems:** None.
    ///
    /// **Example:**
    ///
    /// ```rust
    /// std::fs::create_dir("foo")
    /// ```
    /// Use instead:
    /// ```rust
    /// std::fs::create_dir_all("foo")
    /// ```
    pub CREATE_DIR,
    restriction,
    "calling `std::fs::create_dir` instead of `std::fs::create_dir_all`"
}

declare_lint_pass!(CreateDir => [CREATE_DIR]);

impl LateLintPass<'_> for CreateDir {
    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
        if_chain! {
            if let ExprKind::Call(ref func, ref args) = expr.kind;
            if let ExprKind::Path(ref path) = func.kind;
            if match_qpath(path, &paths::STD_FS_CREATE_DIR);
            then {
                span_lint_and_sugg(
                    cx,
                    CREATE_DIR,
                    expr.span,
                    "calling `std::fs::create_dir` where there may be a better way",
                    "consider calling `std::fs::create_dir_all` instead",
                    format!("std::fs::create_dir_all({})", snippet(cx, args[0].span, "..")),
                    Applicability::MachineApplicable,
                )
            }
        }
    }
}
<commit_msg>Fix clippy error<commit_after>use crate::utils::{match_qpath, paths, snippet, span_lint_and_sugg};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};

declare_clippy_lint! {
    /// **What it does:** Checks usage of `std::fs::create_dir` and suggest using `std::fs::create_dir_all` instead.
    ///
    /// **Why is this bad?** Sometimes `std::fs::crate_dir` is mistakenly chosen over `std::fs::create_dir_all`.
    ///
    /// **Known problems:** None.
    ///
    /// **Example:**
    ///
    /// ```rust
    /// std::fs::create_dir("foo")
    /// ```
    /// Use instead:
    /// ```rust
    /// std::fs::create_dir_all("foo")
    /// ```
    pub CREATE_DIR,
    restriction,
    "calling `std::fs::create_dir` instead of `std::fs::create_dir_all`"
}

declare_lint_pass!(CreateDir => [CREATE_DIR]);

impl LateLintPass<'_> for CreateDir {
    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
        if_chain! {
            if let ExprKind::Call(ref func, ref args) = expr.kind;
            if let ExprKind::Path(ref path) = func.kind;
            if match_qpath(path, &paths::STD_FS_CREATE_DIR);
            then {
                span_lint_and_sugg(
                    cx,
                    CREATE_DIR,
                    expr.span,
                    "calling `std::fs::create_dir` where there may be a better way",
                    "consider calling `std::fs::create_dir_all` instead",
                    format!("std::fs::create_dir_all({})", snippet(cx, args[0].span, "..")),
                    Applicability::MachineApplicable,
                )
            }
        }
    }
}
<|endoftext|>


<commit_before>//! UTF-8 and UTF-16 decoding iterators

use crate::fmt;

use super::from_u32_unchecked;

/// An iterator that decodes UTF-16 encoded code points from an iterator of `u16`s.
#[stable(feature = "decode_utf16", since = "1.9.0")]
#[derive(Clone, Debug)]
pub struct DecodeUtf16<I>
where
    I: Iterator<Item = u16>,
{
    iter: I,
    buf: Option<u16>,
}

/// An error that can be returned when decoding UTF-16 code points.
#[stable(feature = "decode_utf16", since = "1.9.0")]
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct DecodeUtf16Error {
    code: u16,
}

/// Creates an iterator over the UTF-16 encoded code points in `iter`,
/// returning unpaired surrogates as `Err`s.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// use std::char::decode_utf16;
///
/// // 𝄞mus<invalid>ic<invalid>
/// let v = [
///     0xD834, 0xDD1E, 0x006d, 0x0075, 0x0073, 0xDD1E, 0x0069, 0x0063, 0xD834,
/// ];
///
/// assert_eq!(
///     decode_utf16(v.iter().cloned())
///         .map(|r| r.map_err(|e| e.unpaired_surrogate()))
///         .collect::<Vec<_>>(),
///     vec![
///         Ok('𝄞'),
///         Ok('m'), Ok('u'), Ok('s'),
///         Err(0xDD1E),
///         Ok('i'), Ok('c'),
///         Err(0xD834)
///     ]
/// );
/// ```
///
/// A lossy decoder can be obtained by replacing `Err` results with the replacement character:
///
/// ```
/// use std::char::{decode_utf16, REPLACEMENT_CHARACTER};
///
/// // 𝄞mus<invalid>ic<invalid>
/// let v = [
///     0xD834, 0xDD1E, 0x006d, 0x0075, 0x0073, 0xDD1E, 0x0069, 0x0063, 0xD834,
/// ];
///
/// assert_eq!(
///     decode_utf16(v.iter().cloned())
///        .map(|r| r.unwrap_or(REPLACEMENT_CHARACTER))
///        .collect::<String>(),
///     "𝄞mus�ic�"
/// );
/// ```
#[stable(feature = "decode_utf16", since = "1.9.0")]
#[inline]
pub fn decode_utf16<I: IntoIterator<Item = u16>>(iter: I) -> DecodeUtf16<I::IntoIter> {
    DecodeUtf16 { iter: iter.into_iter(), buf: None }
}

#[stable(feature = "decode_utf16", since = "1.9.0")]
impl<I: Iterator<Item = u16>> Iterator for DecodeUtf16<I> {
    type Item = Result<char, DecodeUtf16Error>;

    fn next(&mut self) -> Option<Result<char, DecodeUtf16Error>> {
        let u = match self.buf.take() {
            Some(buf) => buf,
            None => self.iter.next()?,
        };

        if u < 0xD800 || 0xDFFF < u {
            // SAFETY: not a surrogate
            Some(Ok(unsafe { from_u32_unchecked(u as u32) }))
        } else if u >= 0xDC00 {
            // a trailing surrogate
            Some(Err(DecodeUtf16Error { code: u }))
        } else {
            let u2 = match self.iter.next() {
                Some(u2) => u2,
                // eof
                None => return Some(Err(DecodeUtf16Error { code: u })),
            };
            if u2 < 0xDC00 || u2 > 0xDFFF {
                // not a trailing surrogate so we're not a valid
                // surrogate pair, so rewind to redecode u2 next time.
                self.buf = Some(u2);
                return Some(Err(DecodeUtf16Error { code: u }));
            }

            // all ok, so lets decode it.
            let c = (((u - 0xD800) as u32) << 10 | (u2 - 0xDC00) as u32) + 0x1_0000;
            // SAFETY: we checked that it's a legal unicode value
            Some(Ok(unsafe { from_u32_unchecked(c) }))
        }
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        let (low, high) = self.iter.size_hint();
        // we could be entirely valid surrogates (2 elements per
        // char), or entirely non-surrogates (1 element per char)
        (low / 2, high)
    }
}

impl DecodeUtf16Error {
    /// Returns the unpaired surrogate which caused this error.
    #[stable(feature = "decode_utf16", since = "1.9.0")]
    pub fn unpaired_surrogate(&self) -> u16 {
        self.code
    }
}

#[stable(feature = "decode_utf16", since = "1.9.0")]
impl fmt::Display for DecodeUtf16Error {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "unpaired surrogate found: {:x}", self.code)
    }
}
<commit_msg>Rollup merge of #87585 - GuillaumeGomez:char-types-doc, r=joshtriplett<commit_after>//! UTF-8 and UTF-16 decoding iterators

use crate::fmt;

use super::from_u32_unchecked;

/// An iterator that decodes UTF-16 encoded code points from an iterator of `u16`s.
///
/// This `struct` is created by the [`decode_utf16`] method on [`char`]. See its
/// documentation for more.
///
/// [`decode_utf16`]: char::decode_utf16
#[stable(feature = "decode_utf16", since = "1.9.0")]
#[derive(Clone, Debug)]
pub struct DecodeUtf16<I>
where
    I: Iterator<Item = u16>,
{
    iter: I,
    buf: Option<u16>,
}

/// An error that can be returned when decoding UTF-16 code points.
///
/// This `struct` is created when using the [`DecodeUtf16`] type.
#[stable(feature = "decode_utf16", since = "1.9.0")]
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct DecodeUtf16Error {
    code: u16,
}

/// Creates an iterator over the UTF-16 encoded code points in `iter`,
/// returning unpaired surrogates as `Err`s.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// use std::char::decode_utf16;
///
/// // 𝄞mus<invalid>ic<invalid>
/// let v = [
///     0xD834, 0xDD1E, 0x006d, 0x0075, 0x0073, 0xDD1E, 0x0069, 0x0063, 0xD834,
/// ];
///
/// assert_eq!(
///     decode_utf16(v.iter().cloned())
///         .map(|r| r.map_err(|e| e.unpaired_surrogate()))
///         .collect::<Vec<_>>(),
///     vec![
///         Ok('𝄞'),
///         Ok('m'), Ok('u'), Ok('s'),
///         Err(0xDD1E),
///         Ok('i'), Ok('c'),
///         Err(0xD834)
///     ]
/// );
/// ```
///
/// A lossy decoder can be obtained by replacing `Err` results with the replacement character:
///
/// ```
/// use std::char::{decode_utf16, REPLACEMENT_CHARACTER};
///
/// // 𝄞mus<invalid>ic<invalid>
/// let v = [
///     0xD834, 0xDD1E, 0x006d, 0x0075, 0x0073, 0xDD1E, 0x0069, 0x0063, 0xD834,
/// ];
///
/// assert_eq!(
///     decode_utf16(v.iter().cloned())
///        .map(|r| r.unwrap_or(REPLACEMENT_CHARACTER))
///        .collect::<String>(),
///     "𝄞mus�ic�"
/// );
/// ```
#[stable(feature = "decode_utf16", since = "1.9.0")]
#[inline]
pub fn decode_utf16<I: IntoIterator<Item = u16>>(iter: I) -> DecodeUtf16<I::IntoIter> {
    DecodeUtf16 { iter: iter.into_iter(), buf: None }
}

#[stable(feature = "decode_utf16", since = "1.9.0")]
impl<I: Iterator<Item = u16>> Iterator for DecodeUtf16<I> {
    type Item = Result<char, DecodeUtf16Error>;

    fn next(&mut self) -> Option<Result<char, DecodeUtf16Error>> {
        let u = match self.buf.take() {
            Some(buf) => buf,
            None => self.iter.next()?,
        };

        if u < 0xD800 || 0xDFFF < u {
            // SAFETY: not a surrogate
            Some(Ok(unsafe { from_u32_unchecked(u as u32) }))
        } else if u >= 0xDC00 {
            // a trailing surrogate
            Some(Err(DecodeUtf16Error { code: u }))
        } else {
            let u2 = match self.iter.next() {
                Some(u2) => u2,
                // eof
                None => return Some(Err(DecodeUtf16Error { code: u })),
            };
            if u2 < 0xDC00 || u2 > 0xDFFF {
                // not a trailing surrogate so we're not a valid
                // surrogate pair, so rewind to redecode u2 next time.
                self.buf = Some(u2);
                return Some(Err(DecodeUtf16Error { code: u }));
            }

            // all ok, so lets decode it.
            let c = (((u - 0xD800) as u32) << 10 | (u2 - 0xDC00) as u32) + 0x1_0000;
            // SAFETY: we checked that it's a legal unicode value
            Some(Ok(unsafe { from_u32_unchecked(c) }))
        }
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        let (low, high) = self.iter.size_hint();
        // we could be entirely valid surrogates (2 elements per
        // char), or entirely non-surrogates (1 element per char)
        (low / 2, high)
    }
}

impl DecodeUtf16Error {
    /// Returns the unpaired surrogate which caused this error.
    #[stable(feature = "decode_utf16", since = "1.9.0")]
    pub fn unpaired_surrogate(&self) -> u16 {
        self.code
    }
}

#[stable(feature = "decode_utf16", since = "1.9.0")]
impl fmt::Display for DecodeUtf16Error {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "unpaired surrogate found: {:x}", self.code)
    }
}
<|endoftext|>


<commit_before>#![feature(test)]
extern crate test;

extern crate num;
extern crate byteorder;
extern crate libc;
extern crate argparse;

use test::Bencher;
use std::env;
use std::fs::File;
use std::io::{Read, Write};
use std::io::Cursor;
use std::mem;
use std::iter::FromIterator;
use byteorder::{ByteOrder, LittleEndian, BigEndian, NativeEndian};
use std::time::Duration;
use argparse::{ArgumentParser, StoreTrue, Store};
use std::process::exit;

use libc::{c_int, size_t};
use std::vec;

type c32 = num::Complex<f32>;

macro_rules! timer_start {
    () => {
        {
            let timer = std::time::Instant::now();
            timer
        }
    }
}

macro_rules! timer_stop {
    ($timer:expr, $name:expr) => {
        let d = ($timer).elapsed();
        println!("elapsed time for {}: {:.7}s.", $name, d.as_secs() as f64 + d.subsec_nanos() as f64 / 1.0e9f64);
    }
}

fn kernel1(ai: &mut Vec<f32>, ef: &Vec<c32>) {
    let size = ai.len();
    for i in 0..size {
        ai[i] += ef[i].re.powi(2) + ef[i].im.powi(2);
    }
}

fn kernel2(ai: &mut Vec<f32>, ef_re: &Vec<f32>, ef_im: &Vec<f32>) {
    let size = ai.len();
    for i in 0..size {
        ai[i] += ef_re[i].powi(2) + ef_im[i].powi(2);
    }
}

fn kernel3(ai: &mut Vec<f32>, ef: &Vec<f32>) {
    let size = ai.len();
    for i in 0..size {
        ai[i] += ef[2*i].powi(2) + ef[2*i+1].powi(2);
    }
}

// now play with kernels written in C/C++
#[link(name = "ckernels")]
extern "C" {
    fn kernel4(L: c_int, ai: *mut f32, ef: *const f32);
    fn kernel5(L: c_int, ai: *mut f32, ef: *const f32);
}

struct Options {
    verbose: bool,
    name: String,
    rep_count: usize,
    kernel_num: isize,
}

fn cook_input_data() -> (Options, Vec<f32>, Vec<c32>) {
    let mut options = Options {
        verbose:   false,
        name:      "./data/add_sum_sq/sum_ef_20077.bin".to_string(),
        rep_count: 10000,
        kernel_num: -1,
    };

    {
        let mut ap = ArgumentParser::new();
        ap.set_description("Time elapsing for add_sum_sq kernels.");
        ap.refer(&mut options.verbose)
            .add_option(&["-v", "--verbose"], StoreTrue,
            "set verbose");
        ap.refer(&mut options.name)
            .add_option(&["-i", "--input"], Store,
            "set name of input file");
        ap.refer(&mut options.rep_count)
            .add_option(&["-n", "--num_iters"], Store,
            "set number of iterations");
        ap.refer(&mut options.kernel_num)
            .add_option(&["-k", "--num_kernel"], Store,
            "set number of kernel");
        match ap.parse_args() {
            Ok(()) => {}
            Err(x) => {
                //exit(x);
                //println!("unlnown option: {}",x);
            }
        }
    }

    if options.verbose {
        println!("input file name : {} number of iterations : {} kernel number : {}",
                 options.name, options.rep_count, options.kernel_num);
    }

    let mut file = File::open(&options.name).ok().expect(&format!("The file {:?} does not exist", &options.name));
    let file_info = file.metadata().ok().expect("Cannot get file metadata");
    if !file_info.is_file() {
        panic!("{:?} is not a file", &options.name);
    }
    println!("the file {:?} has length {} bytes", &options.name, file_info.len());

    let mut buf = [0u8; 4];
    file.read(&mut buf[..]);
    let L = LittleEndian::read_u32(&buf[..]);
    println!("L : {}", L);
    let size = L as usize;
    let mut grid_buf = Vec::new();
    let sz = file.read_to_end(&mut grid_buf).unwrap();
    let ai = Vec::from_iter((0..size).map(|i| {
                let start = i * mem::size_of::<f32>();
                let val = LittleEndian::read_f32(&grid_buf[start .. ]);
                //println!("val : {}",val);
                val
            }));
    let ef = Vec::from_iter((0..size).map(|i| {
                let offset = size * mem::size_of::<f32>();
                let start = offset + i * mem::size_of::<c32>();
                let val_real = LittleEndian::read_f32(&grid_buf[start                         .. ]);
                let val_imag = LittleEndian::read_f32(&grid_buf[start + mem::size_of::<f32>() .. ]);
                //println!("val_real : {}  val_imag : {}",val_real,val_imag);
                c32::new(val_real, val_imag)
            }));

    (options, ai, ef)
}

fn ef_views(ef: &Vec<c32>) -> (Vec<f32>, Vec<f32>, Vec<f32>) {
    let size = ef.len();
    let ef_re = Vec::from_iter((0..size).map(|i| ef[i].re));
    let ef_im = Vec::from_iter((0..size).map(|i| ef[i].im));
    let ef_as_f32 = Vec::from_iter((0..2*size).map(|i| {
                let j = i/2;
                if i%2 == 0 {ef[j].re} else {ef[j].im}
            }));
    (ef_re, ef_im, ef_as_f32)
}

fn main() {

    let (options, mut ai, ef) = cook_input_data();
    let size = ai.len();

    let (ef_re, ef_im, ef_as_f32) = ef_views(&ef);

    let rep_count = options.rep_count;

    if options.kernel_num == 1 || options.kernel_num == -1 {
        let timer = timer_start!();

        for _ in 0..rep_count {
            kernel1(&mut ai, &ef);
        }

        timer_stop!(timer, "kernel1");
    }

    if options.kernel_num == 2 || options.kernel_num == -1 {
        let timer = timer_start!();

        for _ in 0..rep_count {
            kernel2(&mut ai, &ef_re, &ef_im);
        }

        timer_stop!(timer, "kernel2");
    }

    if options.kernel_num == 3 || options.kernel_num == -1 {
        let timer = timer_start!();

        for _ in 0..rep_count {
            kernel3(&mut ai, &ef_as_f32);
        }

        timer_stop!(timer, "kernel3");
    }

    if options.kernel_num == 4 || options.kernel_num == -1 {
        let len = size as c_int;
        let pai = ai.as_mut_ptr();
        let pef = ef_as_f32.as_ptr();
        let timer = timer_start!();

        for _ in 0..rep_count {
            unsafe {
                kernel4(len, pai, pef);
            }
        }

        timer_stop!(timer, "kernel4");
    }

    if options.kernel_num == 5 || options.kernel_num == -1 {
        let len = size as c_int;
        let pai = ai.as_mut_ptr();
        let pef = ef_as_f32.as_ptr();
        let timer = timer_start!();

        for _ in 0..rep_count {
            unsafe {
                kernel5(len, pai, pef);
            }
        }

        timer_stop!(timer, "kernel5");
    }

    println!("fini");
}

#[bench]
fn setup_kernel4(b: &mut Bencher) {
    let (_, mut ai, ef) = cook_input_data();
    let size = ai.len();

    let (ef_re, ef_im, ef_as_f32) = ef_views(&ef);

    let len = size as c_int;
    let pai = ai.as_mut_ptr();
    let pef = ef_as_f32.as_ptr();

    b.iter(|| {
        unsafe {
            kernel4(len, pai, pef);
        }
    } )
}

<commit_msg>added benches for remaining kernels.<commit_after>#![feature(test)]
extern crate test;

extern crate num;
extern crate byteorder;
extern crate libc;
extern crate argparse;

use test::Bencher;
use std::env;
use std::fs::File;
use std::io::{Read, Write};
use std::io::Cursor;
use std::mem;
use std::iter::FromIterator;
use byteorder::{ByteOrder, LittleEndian, BigEndian, NativeEndian};
use std::time::Duration;
use argparse::{ArgumentParser, StoreTrue, Store};
use std::process::exit;

use libc::{c_int, size_t};
use std::vec;

type c32 = num::Complex<f32>;

macro_rules! timer_start {
    () => {
        {
            let timer = std::time::Instant::now();
            timer
        }
    }
}

macro_rules! timer_stop {
    ($timer:expr, $name:expr) => {
        let d = ($timer).elapsed();
        println!("elapsed time for {}: {:.7}s.", $name, d.as_secs() as f64 + d.subsec_nanos() as f64 / 1.0e9f64);
    }
}

fn kernel1(ai: &mut Vec<f32>, ef: &Vec<c32>) {
    let size = ai.len();
    for i in 0..size {
        ai[i] += ef[i].re.powi(2) + ef[i].im.powi(2);
    }
}

fn kernel2(ai: &mut Vec<f32>, ef_re: &Vec<f32>, ef_im: &Vec<f32>) {
    let size = ai.len();
    for i in 0..size {
        ai[i] += ef_re[i].powi(2) + ef_im[i].powi(2);
    }
}

fn kernel3(ai: &mut Vec<f32>, ef: &Vec<f32>) {
    let size = ai.len();
    for i in 0..size {
        ai[i] += ef[2*i].powi(2) + ef[2*i+1].powi(2);
    }
}

// now play with kernels written in C/C++
#[link(name = "ckernels")]
extern "C" {
    fn kernel4(L: c_int, ai: *mut f32, ef: *const f32);
    fn kernel5(L: c_int, ai: *mut f32, ef: *const f32);
}

struct Options {
    verbose: bool,
    name: String,
    rep_count: usize,
    kernel_num: isize,
}

fn cook_input_data(parse_options: bool) -> (Options, Vec<f32>, Vec<c32>) {
    let mut options = Options {
        verbose:   false,
        name:      "./data/add_sum_sq/sum_ef_20077.bin".to_string(),
        rep_count: 10000,
        kernel_num: -1,
    };

    if parse_options {
        let mut ap = ArgumentParser::new();
        ap.set_description("Time elapsing for add_sum_sq kernels.");
        ap.refer(&mut options.verbose)
            .add_option(&["-v", "--verbose"], StoreTrue,
            "set verbose");
        ap.refer(&mut options.name)
            .add_option(&["-i", "--input"], Store,
            "set name of input file");
        ap.refer(&mut options.rep_count)
            .add_option(&["-n", "--num_iters"], Store,
            "set number of iterations");
        ap.refer(&mut options.kernel_num)
            .add_option(&["-k", "--num_kernel"], Store,
            "set number of kernel");
        match ap.parse_args() {
            Ok(()) => {}
            Err(x) => {
                exit(x);
            }
        }
    }

    if options.verbose {
        println!("input file name : {} number of iterations : {} kernel number : {}",
                 options.name, options.rep_count, options.kernel_num);
    }

    let mut file = File::open(&options.name).ok().expect(&format!("The file {:?} does not exist", &options.name));
    let file_info = file.metadata().ok().expect("Cannot get file metadata");
    if !file_info.is_file() {
        panic!("{:?} is not a file", &options.name);
    }

    if parse_options {
        println!("the file {:?} has length {} bytes", &options.name, file_info.len());
    }

    let mut buf = [0u8; 4];
    file.read(&mut buf[..]);
    let L = LittleEndian::read_u32(&buf[..]);

    if parse_options {
        println!("L : {}", L);
    }

    let size = L as usize;
    let mut grid_buf = Vec::new();
    let sz = file.read_to_end(&mut grid_buf).unwrap();
    let ai = Vec::from_iter((0..size).map(|i| {
                let start = i * mem::size_of::<f32>();
                let val = LittleEndian::read_f32(&grid_buf[start .. ]);
                //println!("val : {}",val);
                val
            }));
    let ef = Vec::from_iter((0..size).map(|i| {
                let offset = size * mem::size_of::<f32>();
                let start = offset + i * mem::size_of::<c32>();
                let val_real = LittleEndian::read_f32(&grid_buf[start                         .. ]);
                let val_imag = LittleEndian::read_f32(&grid_buf[start + mem::size_of::<f32>() .. ]);
                //println!("val_real : {}  val_imag : {}",val_real,val_imag);
                c32::new(val_real, val_imag)
            }));

    (options, ai, ef)
}

fn ef_views(ef: &Vec<c32>) -> (Vec<f32>, Vec<f32>, Vec<f32>) {
    let size = ef.len();
    let ef_re = Vec::from_iter((0..size).map(|i| ef[i].re));
    let ef_im = Vec::from_iter((0..size).map(|i| ef[i].im));
    let ef_as_f32 = Vec::from_iter((0..2*size).map(|i| {
                let j = i/2;
                if i%2 == 0 {ef[j].re} else {ef[j].im}
            }));
    (ef_re, ef_im, ef_as_f32)
}

fn main() {

    let (options, mut ai, ef) = cook_input_data(true);
    let size = ai.len();

    let (ef_re, ef_im, ef_as_f32) = ef_views(&ef);

    let rep_count = options.rep_count;

    if options.kernel_num == 1 || options.kernel_num == -1 {
        let timer = timer_start!();

        for _ in 0..rep_count {
            kernel1(&mut ai, &ef);
        }

        timer_stop!(timer, "kernel1");
    }

    if options.kernel_num == 2 || options.kernel_num == -1 {
        let timer = timer_start!();

        for _ in 0..rep_count {
            kernel2(&mut ai, &ef_re, &ef_im);
        }

        timer_stop!(timer, "kernel2");
    }

    if options.kernel_num == 3 || options.kernel_num == -1 {
        let timer = timer_start!();

        for _ in 0..rep_count {
            kernel3(&mut ai, &ef_as_f32);
        }

        timer_stop!(timer, "kernel3");
    }

    if options.kernel_num == 4 || options.kernel_num == -1 {
        let len = size as c_int;
        let pai = ai.as_mut_ptr();
        let pef = ef_as_f32.as_ptr();
        let timer = timer_start!();

        for _ in 0..rep_count {
            unsafe {
                kernel4(len, pai, pef);
            }
        }

        timer_stop!(timer, "kernel4");
    }

    if options.kernel_num == 5 || options.kernel_num == -1 {
        let len = size as c_int;
        let pai = ai.as_mut_ptr();
        let pef = ef_as_f32.as_ptr();
        let timer = timer_start!();

        for _ in 0..rep_count {
            unsafe {
                kernel5(len, pai, pef);
            }
        }

        timer_stop!(timer, "kernel5");
    }

    println!("fini");
}

#[bench]
fn setup_kernel1(b: &mut Bencher) {
    let (_, mut ai, ef) = cook_input_data(false);

    b.iter(|| {
        kernel1(&mut ai, &ef);
    } )
}

#[bench]
fn setup_kernel2(b: &mut Bencher) {
    let (_, mut ai, ef) = cook_input_data(false);
    let (ef_re, ef_im, _) = ef_views(&ef);

    b.iter(|| {
        kernel2(&mut ai, &ef_re, &ef_im);
    } )
}

#[bench]
fn setup_kernel3(b: &mut Bencher) {
    let (_, mut ai, ef) = cook_input_data(false);
    let (_, _, ef_as_f32) = ef_views(&ef);

    b.iter(|| {
        kernel3(&mut ai, &ef_as_f32);
    } )
}

#[bench]
fn setup_kernel4(b: &mut Bencher) {
    let (_, mut ai, ef) = cook_input_data(false);
    let size = ai.len();

    let (ef_re, ef_im, ef_as_f32) = ef_views(&ef);

    let len = size as c_int;
    let pai = ai.as_mut_ptr();
    let pef = ef_as_f32.as_ptr();

    b.iter(|| {
        unsafe {
            kernel4(len, pai, pef);
        }
    } )
}

#[bench]
fn setup_kernel5(b: &mut Bencher) {
    let (_, mut ai, ef) = cook_input_data(false);
    let size = ai.len();

    let (ef_re, ef_im, ef_as_f32) = ef_views(&ef);

    let len = size as c_int;
    let pai = ai.as_mut_ptr();
    let pef = ef_as_f32.as_ptr();

    b.iter(|| {
        unsafe {
            kernel5(len, pai, pef);
        }
    } )
}

<|endoftext|>


<commit_before>// Copyright (c) 2017 FaultyRAM
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT
// or http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.

//! Types for safely allocating memory.

#![cfg_attr(feature = "clippy", allow(inline_always))]

use core::{fmt, isize};
use core::ptr::Unique;
use super::error::Error;
use super::result::Result;

extern "C" {
    #[allocator]
    fn __rust_allocate(len: usize, align: usize) -> *mut u8;
    fn __rust_allocate_zeroed(len: usize, align: usize) -> *mut u8;
    fn __rust_deallocate(ptr: *mut u8, old_len: usize, align: usize);
    fn __rust_reallocate(ptr: *mut u8, old_len: usize, len: usize, align: usize) -> *mut u8;
    fn __rust_reallocate_inplace(ptr: *mut u8, old_len: usize, len: usize, align: usize) -> usize;
}

#[cfg_attr(feature = "clippy", allow(cast_sign_loss))]
#[inline(always)]
/// Performs sanity checks on the length of a requested memory allocation.
fn check_len(len: usize) -> Result<()> {
    if len == 0 {
        Err(Error::ZeroLength)
    } else if len > isize::MAX as usize {
        Err(Error::NotEnoughMemory)
    } else {
        Ok(())
    }
}

#[inline(always)]
/// Performs sanity checks on the length and alignment of a requested memory allocation.
fn check_len_and_align(len: usize, align: usize) -> Result<()> {
    check_len(len).and_then(
        |_| if usize::is_power_of_two(align) {
            Ok(())
        } else {
            Err(Error::BadAlignment)
        }
    )
}

#[allow(missing_copy_implementations)]
/// An owned, allocated block of memory.
pub struct Allocation {
    /// A raw pointer to the allocated block of memory.
    ptr: Unique<u8>,
    /// The length in bytes of the allocation.
    len: usize,
    /// The alignment in bytes of the allocation.
    align: usize,
}

#[cfg_attr(feature = "clippy", allow(len_without_is_empty))]
impl Allocation {
    #[inline]
    /// Allocates a block of memory using the specified length and alignment.
    pub fn new(len: usize, align: usize) -> Result<Allocation> {
        check_len_and_align(len, align).and_then(
            |_| {
                let ptr = unsafe { __rust_allocate(len, align) };
                if ptr.is_null() {
                    Err(Error::NotEnoughMemory)
                } else {
                    Ok(
                        Allocation {
                            ptr: unsafe { Unique::new(ptr) },
                            len: len,
                            align: align,
                        }
                    )
                }
            }
        )
    }

    #[inline]
    /// Allocates a block of memory with all bytes initialized to zero, using the specified length
    /// and alignment.
    pub fn zeroed(len: usize, align: usize) -> Result<Allocation> {
        check_len_and_align(len, align).and_then(
            |_| {
                let ptr = unsafe { __rust_allocate_zeroed(len, align) };
                if ptr.is_null() {
                    Err(Error::NotEnoughMemory)
                } else {
                    Ok(
                        Allocation {
                            ptr: unsafe { Unique::new(ptr) },
                            len: len,
                            align: align,
                        }
                    )
                }
            }
        )
    }

    #[inline]
    /// Resizes an existing allocation.
    ///
    /// On failure, returns an error without modifying the existing allocation.
    pub fn resize(&mut self, new_len: usize) -> Result<()> {
        check_len(new_len).and_then(
            |_| {
                let ptr =
                    unsafe { __rust_reallocate(self.as_mut_ptr(), self.len, new_len, self.align) };
                if ptr.is_null() {
                    Err(Error::NotEnoughMemory)
                } else {
                    self.ptr = unsafe { Unique::new(ptr) };
                    self.len = new_len;
                    Ok(())
                }
            }
        )
    }

    #[inline]
    /// Resizes an existing allocation without moving it.
    ///
    /// On failure, returns an error without modifying the existing allocation.
    pub fn resize_in_place(&mut self, new_len: usize) -> Result<()> {
        check_len(new_len).and_then(
            |_| {
                self.len = unsafe {
                    __rust_reallocate_inplace(self.as_mut_ptr(), self.len, new_len, self.align)
                };
                Ok(())
            }
        )
    }

    /// Returns a raw pointer to the allocated block of memory.
    pub fn as_ptr(&self) -> *const u8 {
        unsafe { &*self.ptr.as_ptr() }
    }

    /// Returns a mutable raw pointer to the allocated block of memory.
    pub fn as_mut_ptr(&mut self) -> *mut u8 {
        self.ptr.as_ptr()
    }

    /// Returns the length in bytes of the allocated block of memory.
    pub fn len(&self) -> usize {
        self.len
    }

    /// Returns the alignment in bytes of the allocated block of memory.
    pub fn align(&self) -> usize {
        self.align
    }
}

impl Drop for Allocation {
    fn drop(&mut self) {
        unsafe {
            __rust_deallocate(self.ptr.as_ptr(), self.len, self.align);
        }
    }
}

impl fmt::Debug for Allocation {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("Allocation")
            .field("ptr", &self.ptr.as_ptr())
            .field("len", &self.len)
            .field("align", &self.align)
            .finish()
    }
}
<commit_msg>Add `#[inline]` attribute to `Allocation` destructor<commit_after>// Copyright (c) 2017 FaultyRAM
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT
// or http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.

//! Types for safely allocating memory.

#![cfg_attr(feature = "clippy", allow(inline_always))]

use core::{fmt, isize};
use core::ptr::Unique;
use super::error::Error;
use super::result::Result;

extern "C" {
    #[allocator]
    fn __rust_allocate(len: usize, align: usize) -> *mut u8;
    fn __rust_allocate_zeroed(len: usize, align: usize) -> *mut u8;
    fn __rust_deallocate(ptr: *mut u8, old_len: usize, align: usize);
    fn __rust_reallocate(ptr: *mut u8, old_len: usize, len: usize, align: usize) -> *mut u8;
    fn __rust_reallocate_inplace(ptr: *mut u8, old_len: usize, len: usize, align: usize) -> usize;
}

#[cfg_attr(feature = "clippy", allow(cast_sign_loss))]
#[inline(always)]
/// Performs sanity checks on the length of a requested memory allocation.
fn check_len(len: usize) -> Result<()> {
    if len == 0 {
        Err(Error::ZeroLength)
    } else if len > isize::MAX as usize {
        Err(Error::NotEnoughMemory)
    } else {
        Ok(())
    }
}

#[inline(always)]
/// Performs sanity checks on the length and alignment of a requested memory allocation.
fn check_len_and_align(len: usize, align: usize) -> Result<()> {
    check_len(len).and_then(
        |_| if usize::is_power_of_two(align) {
            Ok(())
        } else {
            Err(Error::BadAlignment)
        }
    )
}

#[allow(missing_copy_implementations)]
/// An owned, allocated block of memory.
pub struct Allocation {
    /// A raw pointer to the allocated block of memory.
    ptr: Unique<u8>,
    /// The length in bytes of the allocation.
    len: usize,
    /// The alignment in bytes of the allocation.
    align: usize,
}

#[cfg_attr(feature = "clippy", allow(len_without_is_empty))]
impl Allocation {
    #[inline]
    /// Allocates a block of memory using the specified length and alignment.
    pub fn new(len: usize, align: usize) -> Result<Allocation> {
        check_len_and_align(len, align).and_then(
            |_| {
                let ptr = unsafe { __rust_allocate(len, align) };
                if ptr.is_null() {
                    Err(Error::NotEnoughMemory)
                } else {
                    Ok(
                        Allocation {
                            ptr: unsafe { Unique::new(ptr) },
                            len: len,
                            align: align,
                        }
                    )
                }
            }
        )
    }

    #[inline]
    /// Allocates a block of memory with all bytes initialized to zero, using the specified length
    /// and alignment.
    pub fn zeroed(len: usize, align: usize) -> Result<Allocation> {
        check_len_and_align(len, align).and_then(
            |_| {
                let ptr = unsafe { __rust_allocate_zeroed(len, align) };
                if ptr.is_null() {
                    Err(Error::NotEnoughMemory)
                } else {
                    Ok(
                        Allocation {
                            ptr: unsafe { Unique::new(ptr) },
                            len: len,
                            align: align,
                        }
                    )
                }
            }
        )
    }

    #[inline]
    /// Resizes an existing allocation.
    ///
    /// On failure, returns an error without modifying the existing allocation.
    pub fn resize(&mut self, new_len: usize) -> Result<()> {
        check_len(new_len).and_then(
            |_| {
                let ptr =
                    unsafe { __rust_reallocate(self.as_mut_ptr(), self.len, new_len, self.align) };
                if ptr.is_null() {
                    Err(Error::NotEnoughMemory)
                } else {
                    self.ptr = unsafe { Unique::new(ptr) };
                    self.len = new_len;
                    Ok(())
                }
            }
        )
    }

    #[inline]
    /// Resizes an existing allocation without moving it.
    ///
    /// On failure, returns an error without modifying the existing allocation.
    pub fn resize_in_place(&mut self, new_len: usize) -> Result<()> {
        check_len(new_len).and_then(
            |_| {
                self.len = unsafe {
                    __rust_reallocate_inplace(self.as_mut_ptr(), self.len, new_len, self.align)
                };
                Ok(())
            }
        )
    }

    /// Returns a raw pointer to the allocated block of memory.
    pub fn as_ptr(&self) -> *const u8 {
        unsafe { &*self.ptr.as_ptr() }
    }

    /// Returns a mutable raw pointer to the allocated block of memory.
    pub fn as_mut_ptr(&mut self) -> *mut u8 {
        self.ptr.as_ptr()
    }

    /// Returns the length in bytes of the allocated block of memory.
    pub fn len(&self) -> usize {
        self.len
    }

    /// Returns the alignment in bytes of the allocated block of memory.
    pub fn align(&self) -> usize {
        self.align
    }
}

impl Drop for Allocation {
    #[inline]
    fn drop(&mut self) {
        unsafe {
            __rust_deallocate(self.ptr.as_ptr(), self.len, self.align);
        }
    }
}

impl fmt::Debug for Allocation {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("Allocation")
            .field("ptr", &self.ptr.as_ptr())
            .field("len", &self.len)
            .field("align", &self.align)
            .finish()
    }
}
<|endoftext|>