A Programmable Processing-In-Memory Architecture For Memory Intensive Applications