Posts tagged ‘.Net’

Book Review – Real World Functional Programming

Real World Functional Programming

Real-World functional programming has been written by Tomas Petricek and Jon Skeet.
Tomasz’s and Jon’s book is built around how to think functionally when programming and how to make best use of functional paradigm for real world scenerios. The book is written  mainly for the C# programmers who would like to switch/learn more of the functional world. It also features snippets with some technical background of the ideas involved.
As the title suggests the book is not focussed on one language, instead a mix of C# and F#, and it does a great job in bringing these worlds together,which is to me best of both worlds. Although, samples are all in functional style, when the problem needs the functional beauty to express, F# takes place. This gives any .NET developer to see when to use the necessary language for a particular problem.

The book starts slowly with the functional structures, and goes to monads, and to reactive libraries.  I found the language of the book clear to understand, and easy to follow. The samples in the beginning of a chapter starts with some really simple constructs, but at the end of a chapter they become more complicated, and a nice programs to reflect the idea of the chapter.

Applied functional programming is probably the most sophisticated part of the book. Some ideas mainly inspired from research papers (cited at the end) blended with modern languages and libraries and applied somewhat differently. Especially composable functional libraries and reactive functional programs were insightful and open the mind with new possibilities.

Finally, I would recommend this book whoever wants to switch to functional programming and also learn new techniques in general. Each sample is crafted well, and represent real value with its tutorial writing style.

Distributed Functional Programming with F# MPI Tools for .NET

Introduction

For many years, parallel computing is an important area for research in high performance computing. Super computers dominated the industry all the time. However with the cost of obtaining a fast computer and a fast network, cluster computing considered as a good alternative. High Performance Computing market grew rapidly, mainly because of the clusters intensified. According to a research, clusters represent 50% of the High Performance Computing system revenue at the end of 2005.

The idea of cluster computing is to have many machines on a high-speed network, clusters of computers running the same program. Recently, with the invention and adoption of multi-core CPU systems for desktops, it has become even more important. MPI makes even easier for people to build supercomputers by the usage of powerful computers, high speed networks and powerful libraries.

Message Passing Interface (MPI) is the standard of message passing in a distributed computing environment. Its benefit for researchers is invaluable.

MPICH is an open source, portable implementation of Message Passing Interface (MPI) for developing distributed memory application .

The goal of MPI Tools is to make easy to write programs that runs on a cluster of machines. Also make the transition and the portability easy for existing programs in cluster. Using MPITools, it is possible to create distributed functional applications with F#. Although it is primarily developed for .NET framework, it can run on any CLI implementation.

Implementation

The first step involved to make MPICH available to use for F# platform. A wrapping library is implemented for MPICH. Mainly used MPICH functions made available to F#. Those MPI functions are implemented with the effective usage of types. MPI_Init,, MPI_Comm_size, MPI_Comm_rank, MPI_Finalize, MPI_Send, MPI_Recv, MPI_Abort,  MPI_Barrier, MPI_Bcast , MPI_Gather, MPI_Scatter, MPI_Reduce. In reality, you could write distributed programs with just the first six of those function as I will show on the samples.  When using the library you don’t have to worry about the types and data sizes as you usually do in C programming. The only thing important is the order of communication the same as socket programming.

Because MPICH is unmanaged library, it important to make the data types compatible using the interoperability libraries in .NET framework.  All of the exposed data types and functions are defined in “mpi.h” file in MPICH distribution. If you want to use a different MPI implementation then it is needed to change those functions definitions appropriately based on the documentation.

[]
extern int MPI_Send( void *buf, int count, int MPI_Datatype,
int dest, int tag, int MPI_Comm)

Once the value data types such as int, char, byte, double and float types implemented which are pretty same with C implementation. Next step was to make the reference types of the virtual machine available. Unfortunately not all reference types are possible to send out to wire because of the state or impureness of the type. The types have to be serializable in order to send or receive. To make that possible binary serialization is used and passed as a byte array to the MPI. Implementing the reference types made also possible to pass the functions and lambda functions in to the channel.

For the MPI development, the key factor is the data types. The parties have to agree with the file types. Also the size of the file types should be fixed in order to communicate. However the types are properly handled by the library using the sophisticated type system capabilities. In the programs the order becomes really important. In order to get to the internals of MPI Tools, here is an implementation for standard MPICH type definitions and a type converter for it (shortened for simplicity).

type MPI_Datatype =
| MPI_CHAR           =  0x4c000101
| MPI_SIGNED_CHAR    =  0x4c000118

let private TypeConvert (t) =
let res =
match (box t) with
| : ? byte -> MPI_Datatype.MPI_BYTE
| : ? char -> MPI_Datatype.MPI_CHAR
| _ -> failwith “not implemented data type
Enum.to_int res

The complicated, many parameter function calls in the unmanaged MPICH library becomes powerful function with a few arguments in the .NET library. For instance previously defined 6 argument MPI_Send function becomes a three argument polymorphic function. To make it easy, actually send function becomes in different flavours. Actually most of the communication functions come in different versions for different types. The version below is used for singular types. There are two more flavours one for arrays and other for matrix types.

let send(data,destination, tag)
'a * int * int -> unit

let sendArray(data : 'a array,destination,tag)
a array * int * int -> unit

let sendMatrix (data : matrix,destination,tag)
matrix * int * int -> unit

Similarly, the same pattern goes for the receive function. However, this time it is needed to specify the return type as a generic argument of the function.

let receive<'a>(source,tag)
int*int -> 'a
 
let receiveArray<'a> (source, tag)
int * int -> 'a array
 
let receiveMatrix(source, tag)
int * int -> matrix

The other functions of MPI are implemented in a similar manner. You could also check the project as a tutorial as well. The library uses effectively active patterns, discriminated unions, interoperability and other functional structures

Usage

First of all MPICH needs to be installed prior to usage. The library is used just like another .NET library in your programs. However the execution is relatively different than usual. The programs have to be executed using the MPI daemon called "mpiexec". You could look at more on how to configure a cluster in the MPICH documentation. To run the process in n processor or processes “-n” switch needs to be given as a command line argument followed by the name of the compiled program.

mpiexec -n 2 test.exe

Here is a very simple ping pong application using MPI Tools. You can find more samples on the MPI Tools Source code.

#light
#I @"..\MPITools.Bindings\"
#r @"MPITools.Bindings.dll"
open MPITools
MPI.initialize()
 
let procSize = MPI.size()
let curProcess =  MPI.rank()
 
let pingpong() =
if curProcess = 0 then
let i =  0
MPI.send(i,1,0)
let b = MPI.receive(1,0)
()
elif curProcess = 1 then
let b = MPI.receive(0,0)
MPI.send(b+1,0,0)
pingpong()
MPI.finalize()

Conclusion

You can download MPI Tools from codeplex. Using MPI Tools, the distributed programs will be short, expressive and well typed with the help of the glorified type system of F#.

MPI Tools is built with F# 1.9.3.7 Compiler for the .NET Framework 2.0. However it would possibly work with any CLI implementation. In the future, some more MPI functions will be implemented, including some helper functions that hides the imperative style programming. and the side effects.

I hope it will help to solve your high computation problems effectively. Please feel free to ask questions or to contribute to the project.

Have fun!

Parallelism on October’s MSDN Magazine

Although I am extremely busy this month, I can’t stop reading those wonderful articles about parallelism on October’s MSDN Magazine. Here are the articles, a very first gentle introduction to PLINQ (Parallel LINQ) by Joe Duffy,Ed Essey, Parallel Performance using System.Concurrency namespace and a ThreadPool article. Apparently in the near future we will have some more concurrency dlls.

Going back to work, enjoy!

Simple but Elegant, Creating a class from String

Creating a class from a string might be crucial for some very dynamic projects. It’s a single line of code that I wanted to share but I think it has a lot of power.

Simply get the executing assembly and call the GetType method. If your assembly is one of the linked assembly or even a dynamically loaded assembly, you might need to call GetReferencedAssemblies() method as well.

namespace reflectme
{
    using System;
    public class hello
    {
        public hello()
        {
            Console.WriteLine("hello");
            Console.ReadLine();
        }
        static void Main(string[] args)
        {
            Type t = System.Reflection.Assembly.GetExecutingAssembly().GetType("reflectme.hello");
            t.GetConstructor(System.Type.EmptyTypes).Invoke(null);
        }
    }
}

Bear in mind it will be extremely slow. Don’t do that :)

WebDD – conference in Reading for web developers and web designers – Registration is Open

WebDD , a free confence in Reading for web developers and web designers, registration is open. It is organized by community and hosted by Microsoft. It is on Saturday 3rd February 2007 at Microsoft Reading, UK. Scott Guthrie will be there. You can find the speakers list and sessions.

There will be also a Geek Dinner like previous DDD events. The registration for the dinner is wiki style as previously. I will be there as well.

See you there.

Reflection for Properties and Fields with DynamicMethod

Lastly I posted about the coolest exception while working with System.Reflection.Dynamicmethod class. I found the solution for my bug, and now it works like a charm. There are two classes for accessing properties or fields, one with the generic implementations and one with object implementation. Using the reflection with dynamicmethod reflection we can get 80% more performance compared to traditional reflection. 

Be careful if you are about to use classes that have generic classes as properties. There are some problems with it.

Property that might cause problems of a class

 public class aField<T>
	{
		private T m_Value;
 
 
        public override string ToString()
        {
            return Value.ToString();
        }
 public interface IEntity
    {
         aField<string> CREUSER
        {
            get;
            set;
        }

.

Code for object

using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Reflection.Emit;
 
namespace CE.Reflection
{
    public class DynamicReflectionHelper
    {
        public delegate object GetPropertyFieldDelegate(object obj);
        public static GetPropertyFieldDelegate GetPropertyorField(PropertyInfo pi, FieldInfo fi)
        {
            if (pi != null && fi != null)
                throw new NotSupportedException("one of the parameters should be null");
 
            if (pi != null || fi != null)
            {
                string methodName = string.Empty;
                if (pi != null)
                    methodName = pi.Name;
                else
                    methodName = fi.Name;
 
                Module mod = null;
                if (pi != null)
                    mod = pi.Module;
                else
                    mod = fi.Module;
 
 
                DynamicMethod dm = new DynamicMethod("GetPropertyorField_" + methodName, typeof(object), new Type[] { typeof(object) }, mod, true);
                ILGenerator il = dm.GetILGenerator();
 
                il.Emit(OpCodes.Ldarg_0);
                if (pi != null)
                {
                    il.EmitCall(OpCodes.Callvirt, pi.GetGetMethod(), null);
                    if (pi.PropertyType.IsValueType)
                    {
                        il.Emit(OpCodes.Box, pi.PropertyType);
                    }
                }
                else if (fi != null)
                {
                    il.Emit(OpCodes.Ldfld, fi);
                    if (fi.FieldType.IsValueType)
                    {
                        il.Emit(OpCodes.Box, fi.FieldType);
                    }
                }
 
 
                il.Emit(OpCodes.Ret);
 
                return (GetPropertyFieldDelegate)dm.CreateDelegate(typeof(GetPropertyFieldDelegate));
 
            }
            else
                throw new NullReferenceException("no field or property");
        }
        public static GetPropertyFieldDelegate GetPropertyorField(object o, string memberName)
        {
            Type v = o.GetType();
            PropertyInfo pi = v.GetProperty(memberName);
            FieldInfo fi = v.GetField(memberName);
 
            return GetPropertyorField(pi, fi);
 
        }
 
        public delegate void SetPropertyFieldDelegate(object obj, object m_Value);
 
        public static SetPropertyFieldDelegate SetProperyorField(object o, string memberName)
        {
            Type v = o.GetType();
            PropertyInfo pi = v.GetProperty(memberName);
            FieldInfo fi = v.GetField(memberName);
 
 
            return SetProperyorField(pi, fi);
 
        }
 
        public static SetPropertyFieldDelegate SetProperyorField(PropertyInfo pi, FieldInfo fi)
        {
            if (pi != null && fi != null)
                throw new NotSupportedException("one of the parameters should be null");
            if (pi != null || fi != null)
            {
                string methodName = string.Empty;
                if (pi != null)
                    methodName = pi.Name;
                else
                    methodName = fi.Name;
 
                DynamicMethod dm = new DynamicMethod("SetPropertyorField_" + methodName, typeof(void),
                    new Type[] { typeof(object), typeof(object) }, pi.Module, true);
                ILGenerator il = dm.GetILGenerator();
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldarg_1);
 
 
                if (pi != null)
                {
                    il.EmitCall(OpCodes.Callvirt, pi.GetSetMethod(true), null);
 
                    if (pi.PropertyType.IsValueType)
                    {
                        il.Emit(OpCodes.Unbox_Any, pi.PropertyType);
                    }
                }
                else
                {
                    il.Emit(OpCodes.Stfld, fi);
                    if (pi.PropertyType.IsValueType)
                    {
                        il.Emit(OpCodes.Unbox_Any, pi.PropertyType);
                    }
                }
 
 
                il.Emit(OpCodes.Ret);
 
                return (SetPropertyFieldDelegate)dm.CreateDelegate(typeof(SetPropertyFieldDelegate));
            }
            else
            {
                throw new NullReferenceException("no field or property");
            }
        }
    }
}

Code for generic object

using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Reflection.Emit;
 
namespace CE.Reflection
{
    public class DynamicReflectionHelperforObject<V>
    {
        public delegate T GetPropertyFieldDelegate<T>(V obj);
 
 
        public static GetPropertyFieldDelegate<C> GetP<C>(string memberName)
        {
            Type v = typeof(V);
            PropertyInfo pi = v.GetProperty(memberName);
            FieldInfo fi = v.GetField(memberName);
 
            if (pi != null || fi != null)
            {
                DynamicMethod dm = new DynamicMethod("GetPropertyorField_" + memberName, typeof(C), new Type[] { v }, v.Module);
                ILGenerator il = dm.GetILGenerator();
 
                il.Emit(OpCodes.Ldarg_0); // loaded c, c is the return value
                if (pi != null)
                    il.EmitCall(OpCodes.Call, pi.GetGetMethod(), null);
                else if (fi != null)
                    il.Emit(OpCodes.Ldfld, fi);
                il.Emit(OpCodes.Ret);
 
                return (GetPropertyFieldDelegate<C>)dm.CreateDelegate(typeof(GetPropertyFieldDelegate<C>));
 
            }
            else
                throw new NullReferenceException("No Property or Field");
        }
 
        public delegate void SetPropertyFieldDelegate<T>(V obj, T m_Value);
 
        public static SetPropertyFieldDelegate<C> SetP<C>(string memberName, C mValue)
        {
            Type v = typeof(V);
            PropertyInfo pi = v.GetProperty(memberName);
            FieldInfo fi = v.GetField(memberName);
            if (pi != null || fi != null)
            {
                DynamicMethod dm = new DynamicMethod("SetPropertyorField_" + memberName, typeof(void),
                    new Type[] { v, typeof(C) }, v.Module);
                ILGenerator il = dm.GetILGenerator();
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldarg_1);
                if (pi != null)
                    il.EmitCall(OpCodes.Callvirt, pi.GetSetMethod(), new Type[] { typeof(C) });
                else if (fi != null)
                    il.Emit(OpCodes.Stfld, fi);
                il.Emit(OpCodes.Ret);
 
                return (SetPropertyFieldDelegate<C>)dm.CreateDelegate(typeof(SetPropertyFieldDelegate<C>));
            }
            else
                throw new NullReferenceException("No Property or Field");
        }
    }
}

This project has two main classes, one is generic for working with a specified type, and the other is normal object class in which you need to deal with conversion after using it.