Singleton Pattern in Java, Python and C++

An implementation of the singleton pattern must:

  1. ensure that only one instance of the singleton class ever exists
  2. class creates its own singleton pattern instance
  3. provide global access to that instance.

Typically, this is done by:

  1. declaring all constructors of the class to be private
  2. providing a static method that returns a reference to the instance.

Java

//Lazy loading(not recommend)
public class Singleton {  
    private static Singleton instance;  
    private Singleton (){}  
    public static synchronized Singleton getInstance() {  
    if (instance == null) {  
        instance = new Singleton();  
    }  
    return instance;  
    }  
}
//Non-lazy loading(recommend)
public final class Singleton {
    // create instance
    private static final Singleton INSTANCE = new Singleton();
    // set constructor as null, so that no instance will be created 
    private Singleton() {}
    // return this singletion instance 
    public static Singleton getInstance() {
        return INSTANCE;
    }
}
//enum(recommend)
public enum Singleton {  
    INSTANCE;  
    public void dummy() {  
    }  
}
// how to use
 SingletonEnum singleton = SingletonEnum.INSTANCE;
 singleton.dummy();

Python

// Lazy loading
class Singleton(object):
    def __new__(cls, *args, **kw):
        if not hasattr(cls, '_instance'):
            orig = super(Singleton, cls)
            cls._instance = orig.__new__(cls, *args, **kw)
        return cls._instance

class MyClass(Singleton):
    a = 1

//meta class
class Singleton(type):
    _instances = {}
    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
        return cls._instances[cls]

class MyClass(metaclass=Singleton):
     pass

//decorator
from functools import wraps

def singleton(cls):
    instances = {}
    @wraps(cls)
    def getinstance(*args, **kw):
        if cls not in instances:
            instances[cls] = cls(*args, **kw)
        return instances[cls]
    return getinstance

@singleton
class MyClass(object):
    a = 1

C++

#include <iostream>

class Singleton
{
    private:
        /* Here will be the instance stored. */
        static Singleton* instance;

        /* Private constructor to prevent instancing. */
        Singleton();

    public:
        /* Static access method. */
        static Singleton* getInstance();
};

/* Null, because instance will be initialized on demand. */
Singleton* Singleton::instance = 0;

Singleton* Singleton::getInstance()
{
    if (instance == 0)
    {
        instance = new Singleton();
    }

    return instance;
}

Singleton::Singleton()
{}

int main()
{
    //new Singleton(); // Won't work
    Singleton* s = Singleton::getInstance(); // Ok
    Singleton* r = Singleton::getInstance();

    /* The addresses will be the same. */
    std::cout << s << std::endl;
    std::cout << r << std::endl;
}

OpenCV 4.0 released!!!

OpenCV 4.0 has relased since more than 3 years after 3.0 release. As a most wildly used CV libary which can be used to object detection, image classification, moving object detection and human face detecion. It inculds lots of machine learning and state of art computer vision algorithms. Also, it supports bunch of coding languages, like C++, java, python…

Summary of Upgrade

  1. C++ 11 required. Lots of C API from 1.x have removed. CMake >= 3.5.1
  2. New module G-API has been added. It declares image processing task in form of expressions and then submit it for execution – using a number of available backends.
  3. More DNN module supported.
    3.1 Mask-RCNN model. Here is a guid using Tensorflow ojbect detection.
    3.2 Integrated ONNX(Open Neural Network Exchange ) parser.
  4. Kinect Fusion algorithm has been implemented and optimized for CPU and GPU (OpenCL)
  5. QR code detector and decoder
  6. high-quality DIS dense optical flow algorithm has been moved from opencv_contrib to the video module.
  7. Persistence (storing and loading structured data to/from XML, YAML or JSON) in the core module has been completely reimplemented in C++ and lost the C API as well.

MPI non-blocking receiving with OpenMP

A simple prototype

  1. In the cluster, a Master – Slave structure set up. Master node responses to send the task to slave nodes and regularly check the status of all slave nodes(busy or idle). Salve nodes response to split task from master into sub tasks running with multi-threads.
  2. Master node assigns tasks by iterating each row of the first column in the lattice. If all slave nodes are busy, master will waiting for feedback from slave nodes, otherwise master node will send the new task to the idle slave node.
  3. Master node uses non-blocking method(Irecv) to get the feedback from slave node. So that master node is able to check status of all slave nodes as well as receive feedback.
  4. Slave node splits task into subtask by iterating each row of the second column in the lattice, which is running in a dynamic schedule looping. So that each thread can keep busy all time.

Non-blocking MPI

pool[node] is used to record working slave nodes, wait[node] is used to record if MPI_Irecv is running for the working slave node. Then use MPI_Request_get_status to check the status of request.

            //receive result from slave nodes
            for(int node=0; node < (num_nodes-1); node++){
                if(pool[node]==1){
                    if(wait[node]==0){
                        MPI_Irecv(&node_solution[node], 1, MPI_INT, node+1, TAG, MPI_COMM_WORLD,&rq[node]);
                        wait[node]=1;
                    }

                    MPI_Request_get_status(rq[node],&flag[node],NULL);
                    if(flag[node]){
//                         printf("rec by node %d: %d - %d \n",row,node+1,node_solution[node]);
                        total_solution += node_solution[node];
                        pool[node]=0;
                        wait[node]=0;
                    }
                }
            }

How to complie

compile with openmp: mpic++ -fopenmp NQ-MPI.cpp -o NQ
run in mpi: mpirun -np 5 --host arch06,arch07,arch04,arch05,arch08 ./NQ