Friday, October 07, 2011

Add All Subdirectories in CMake

有時候,某個目錄下有那些子目錄要用add_subdirectory加到build system裡是動態的(也就是不能寫死),像是我們用android的repo工具,projects目錄下要掛什麼sub-project完全就是看default.xml,那麼這個時候cmake的add_subdirectory就整個很沒用,所以就只好用regex硬幹...如果有人碰到一樣的問題可以用以下的方法:

file(GLOB all_valid_subdirs RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*/CMakeLists.txt")

foreach(dir ${all_valid_subdirs})
message(STATUS "path = ${dir}")
if(${dir} MATCHES "^([^/]*)//CMakeLists.txt")
string(REGEX REPLACE "^([^/]*)//CMakeLists.txt" "\\1" dir_trimmed ${dir})

Thursday, October 06, 2011

"You've got to find what you love" - Steve

In memorial of our great leader, Steve Jobs.

Full transcript of the Stanford Commencement 2005

I am honored to be with you today at your commencement from one of the finest universities in the world. I never graduated from college. Truth be told, this is the closest I've ever gotten to a college graduation. Today I want to tell you three stories from my life. That's it. No big deal. Just three stories.

The first story is about connecting the dots.

I dropped out of Reed College after the first 6 months, but then stayed around as a drop-in for another 18 months or so before I really quit. So why did I drop out?

It started before I was born. My biological mother was a young, unwed college graduate student, and she decided to put me up for adoption. She felt very strongly that I should be adopted by college graduates, so everything was all set for me to be adopted at birth by a lawyer and his wife. Except that when I popped out they decided at the last minute that they really wanted a girl. So my parents, who were on a waiting list, got a call in the middle of the night asking: "We have an unexpected baby boy; do you want him?" They said: "Of course." My biological mother later found out that my mother had never graduated from college and that my father had never graduated from high school. She refused to sign the final adoption papers. She only relented a few months later when my parents promised that I would someday go to college.

And 17 years later I did go to college. But I naively chose a college that was almost as expensive as Stanford, and all of my working-class parents' savings were being spent on my college tuition. After six months, I couldn't see the value in it. I had no idea what I wanted to do with my life and no idea how college was going to help me figure it out. And here I was spending all of the money my parents had saved their entire life. So I decided to drop out and trust that it would all work out OK. It was pretty scary at the time, but looking back it was one of the best decisions I ever made. The minute I dropped out I could stop taking the required classes that didn't interest me, and begin dropping in on the ones that looked interesting.

It wasn't all romantic. I didn't have a dorm room, so I slept on the floor in friends' rooms, I returned coke bottles for the 5¢ deposits to buy food with, and I would walk the 7 miles across town every Sunday night to get one good meal a week at the Hare Krishna temple. I loved it. And much of what I stumbled into by following my curiosity and intuition turned out to be priceless later on. Let me give you one example:

Reed College at that time offered perhaps the best calligraphy instruction in the country. Throughout the campus every poster, every label on every drawer, was beautifully hand calligraphed. Because I had dropped out and didn't have to take the normal classes, I decided to take a calligraphy class to learn how to do this. I learned about serif and san serif typefaces, about varying the amount of space between different letter combinations, about what makes great typography great. It was beautiful, historical, artistically subtle in a way that science can't capture, and I found it fascinating.

None of this had even a hope of any practical application in my life. But ten years later, when we were designing the first Macintosh computer, it all came back to me. And we designed it all into the Mac. It was the first computer with beautiful typography. If I had never dropped in on that single course in college, the Mac would have never had multiple typefaces or proportionally spaced fonts. And since Windows just copied the Mac, it's likely that no personal computer would have them. If I had never dropped out, I would have never dropped in on this calligraphy class, and personal computers might not have the wonderful typography that they do. Of course it was impossible to connect the dots looking forward when I was in college. But it was very, very clear looking backwards ten years later.

Again, you can't connect the dots looking forward; you can only connect them looking backwards. So you have to trust that the dots will somehow connect in your future. You have to trust in something — your gut, destiny, life, karma, whatever. This approach has never let me down, and it has made all the difference in my life.

My second story is about love and loss.

I was lucky — I found what I loved to do early in life. Woz and I started Apple in my parents garage when I was 20. We worked hard, and in 10 years Apple had grown from just the two of us in a garage into a $2 billion company with over 4000 employees. We had just released our finest creation — the Macintosh — a year earlier, and I had just turned 30. And then I got fired. How can you get fired from a company you started? Well, as Apple grew we hired someone who I thought was very talented to run the company with me, and for the first year or so things went well. But then our visions of the future began to diverge and eventually we had a falling out. When we did, our Board of Directors sided with him. So at 30 I was out. And very publicly out. What had been the focus of my entire adult life was gone, and it was devastating.

I really didn't know what to do for a few months. I felt that I had let the previous generation of entrepreneurs down - that I had dropped the baton as it was being passed to me. I met with David Packard and Bob Noyce and tried to apologize for screwing up so badly. I was a very public failure, and I even thought about running away from the valley. But something slowly began to dawn on me — I still loved what I did. The turn of events at Apple had not changed that one bit. I had been rejected, but I was still in love. And so I decided to start over.

I didn't see it then, but it turned out that getting fired from Apple was the best thing that could have ever happened to me. The heaviness of being successful was replaced by the lightness of being a beginner again, less sure about everything. It freed me to enter one of the most creative periods of my life.

During the next five years, I started a company named NeXT, another company named Pixar, and fell in love with an amazing woman who would become my wife. Pixar went on to create the worlds first computer animated feature film, Toy Story, and is now the most successful animation studio in the world. In a remarkable turn of events, Apple bought NeXT, I returned to Apple, and the technology we developed at NeXT is at the heart of Apple's current renaissance. And Laurene and I have a wonderful family together.

I'm pretty sure none of this would have happened if I hadn't been fired from Apple. It was awful tasting medicine, but I guess the patient needed it. Sometimes life hits you in the head with a brick. Don't lose faith. I'm convinced that the only thing that kept me going was that I loved what I did. You've got to find what you love. And that is as true for your work as it is for your lovers. Your work is going to fill a large part of your life, and the only way to be truly satisfied is to do what you believe is great work. And the only way to do great work is to love what you do. If you haven't found it yet, keep looking. Don't settle. As with all matters of the heart, you'll know when you find it. And, like any great relationship, it just gets better and better as the years roll on. So keep looking until you find it. Don't settle.

My third story is about death.

When I was 17, I read a quote that went something like: "If you live each day as if it was your last, someday you'll most certainly be right." It made an impression on me, and since then, for the past 33 years, I have looked in the mirror every morning and asked myself: "If today were the last day of my life, would I want to do what I am about to do today?" And whenever the answer has been "No" for too many days in a row, I know I need to change something.

Remembering that I'll be dead soon is the most important tool I've ever encountered to help me make the big choices in life. Because almost everything — all external expectations, all pride, all fear of embarrassment or failure - these things just fall away in the face of death, leaving only what is truly important. Remembering that you are going to die is the best way I know to avoid the trap of thinking you have something to lose. You are already naked. There is no reason not to follow your heart.

About a year ago I was diagnosed with cancer. I had a scan at 7:30 in the morning, and it clearly showed a tumor on my pancreas. I didn't even know what a pancreas was. The doctors told me this was almost certainly a type of cancer that is incurable, and that I should expect to live no longer than three to six months. My doctor advised me to go home and get my affairs in order, which is doctor's code for prepare to die. It means to try to tell your kids everything you thought you'd have the next 10 years to tell them in just a few months. It means to make sure everything is buttoned up so that it will be as easy as possible for your family. It means to say your goodbyes.

I lived with that diagnosis all day. Later that evening I had a biopsy, where they stuck an endoscope down my throat, through my stomach and into my intestines, put a needle into my pancreas and got a few cells from the tumor. I was sedated, but my wife, who was there, told me that when they viewed the cells under a microscope the doctors started crying because it turned out to be a very rare form of pancreatic cancer that is curable with surgery. I had the surgery and I'm fine now.

This was the closest I've been to facing death, and I hope it's the closest I get for a few more decades. Having lived through it, I can now say this to you with a bit more certainty than when death was a useful but purely intellectual concept:

No one wants to die. Even people who want to go to heaven don't want to die to get there. And yet death is the destination we all share. No one has ever escaped it. And that is as it should be, because Death is very likely the single best invention of Life. It is Life's change agent. It clears out the old to make way for the new. Right now the new is you, but someday not too long from now, you will gradually become the old and be cleared away. Sorry to be so dramatic, but it is quite true.

Your time is limited, so don't waste it living someone else's life. Don't be trapped by dogma — which is living with the results of other people's thinking. Don't let the noise of others' opinions drown out your own inner voice. And most important, have the courage to follow your heart and intuition. They somehow already know what you truly want to become. Everything else is secondary.

When I was young, there was an amazing publication called The Whole Earth Catalog, which was one of the bibles of my generation. It was created by a fellow named Stewart Brand not far from here in Menlo Park, and he brought it to life with his poetic touch. This was in the late 1960's, before personal computers and desktop publishing, so it was all made with typewriters, scissors, and polaroid cameras. It was sort of like Google in paperback form, 35 years before Google came along: it was idealistic, and overflowing with neat tools and great notions.

Stewart and his team put out several issues of The Whole Earth Catalog, and then when it had run its course, they put out a final issue. It was the mid-1970s, and I was your age. On the back cover of their final issue was a photograph of an early morning country road, the kind you might find yourself hitchhiking on if you were so adventurous. Beneath it were the words: "Stay Hungry. Stay Foolish." It was their farewell message as they signed off. Stay Hungry. Stay Foolish. And I have always wished that for myself. And now, as you graduate to begin anew, I wish that for you.

Stay Hungry. Stay Foolish.

Thank you all very much.

Tuesday, August 30, 2011

VGPU: GPU, Infiniband, Virtualized

最近在公司做的東西,其實還蠻快就弄完的了。這個影片只是簡單的demo一下,接下來就是要加一些文字還有圖片還有對白,就可以準備丟出去了。這個東西基本上就是rCUDA很相似,只是加上Infiniband RDMA的支援,另外還有API跟比較彈性的使用者管理等等。雖然說前天發現rCUDA好像也做完這段了,只是目前還沒有release code,但是我想commercial跟GPL open source的東西還是各有他們的市場吧~

LLVM-based Programming Language Projects

忙到焦頭爛額,一不小心就四個月過去了,實在太久沒更新了...最近在跟LLVM當朋友,其實他還蠻友善的啦,只要用對方法。除了Clang之外,網路上也有很多programming language/compiler是用LLVM寫的,我覺得參考一下蠻有幫助的。

所以以下是我在Google Code還有Github上找的到的LLVM Language Project...
(很明顯這是一篇騙更新的文章) // Lua-to-LLVM // LLVM-to-Javascript // Haskell-to-LLVM // Pascal-to-LLVM // D-to-LLVM // LLVM GC // RSL-to-LLVM // LEC-to-LLVM // Spirit + LLVM Tutorial // Brainfuck-to-LLVM // LLVM PTX Backend Example // Lisp-to-LLVM // ANTLR + LLVM Example // PL0-to-LLVM // Lisp-dialect

Monday, May 30, 2011

無止境的學習 (二)

其實有時候回頭看大學那一段接案時用Visual Studio開發的日子,再看看現在的寫程式的習慣、用的工具、專案的大小,總有種成長很多的感覺。從以前Linux下只會用vim,到現在都用eclipse搞定較大的project,搭配cgdb還有valgrind,其實我覺得比Windows上開發容易多了(雖然之前剛轉到Linux上時花了一陣子適應)。

而一般人剛接觸Linux開發覺得最痛苦的大概就是Makefile了。雖然GNU出了automake,Qt也有qmake,但是我覺得最容易學的大概是cmake了;cmake的語法真的簡單到一個不行,但相對的,也就沒什麼彈性,要寫一些比較複雜的rule就麻煩了;這一點Google SCons倒是做的非常好,畢竟他有Python為基礎,要寫什麼都簡單,但相對的我覺得速度較慢;另外cmake內建支援一堆package,也就是說他事先先幫你把巨集都定好,像是FindCUDA、FindBoost、FindTBB等等,讓開發人員可以很容易的找到某某函式庫的path,然後完成編譯的設定。但是cmake最大的缺點就是語法很不彈性而且很不嚴謹,macro跟function常常會傻傻分不清楚,我覺得cmake的作者肯定沒認真修過compiler或是programming language...

除了軟體之外,這兩年多也學到了一些比較跟硬體有關的技術,主要像是HPC裡常見的GPU還有Infiniband。GPU我想不用多講,從2006年開始玩到現在已經四年半了,中間GPU也經歷過許多代硬體架構的改進,從G80的架構到今天的Fermi,從CUDA 0.2a到4.0b,我覺得GPU這四年真的進化很多;雖然技術不斷的推陳出新,我覺得更重要的是,我開始習慣從更底層去思考系統的運作,不管今天是什麼處理器、什麼assembly、什麼OS、什麼language、什麼compiler,都可以去更深入的思考甚至是最佳化;我覺得這大概是接觸這麼多東西之後最大的收獲吧!

而至於像是Infiniband這種超高速每秒40Gb的網路技術,傳統是用在超級電腦裡的interconnect,但是也慢慢的因為Ethernet的發展緩慢,走入了一般的data center。我們這兩年從什麼都不懂,到完全了解Infiniband的硬體、還有他底層的API還有RDMA的communication model,其實花了很多功夫。在2008年時,我們還完全不知道Infiniband怎麼寫,就先花了二十萬把DDR的switch還有adapter買進來,沒什麼文件,就一本超厚的bible(根本就是他的hardware spec),再加上一支Google來的hello world的測試程式開始,到debug他的driver不能被當shared library載入這種鬼問題,到最後我們丟掉RDMA send/receive模式改用read/write+atomic operation,真的學到很多,過程也蠻有趣的。當初堅持不用MPI這種鬼東西、不走TCP/IP,全部靠libibverbs這個最底層的interface去build我們自己的network engine...現在回頭看,這兩年多來我們還真累積了不少。

剛順手翻了一下大陸很有名的程序員雜誌。這本雜誌我覺得真的是走在時代的尖端,每一期都會探討許多新的技術還有趨勢。像是今年5月這一期,全部都在講cloud computing的技術,光這一點我就真的覺得大陸的programmer是遠比台灣幸福的。我們活在代工王國的世界裡,這些代工廠或是品牌廠,要的就是Android的人才,而且是非常多Android的人才,所以大家都一股腦的去學Android開發,這也造就台灣又繼NB代工大國之後成為手機代工大國,宏達電股價衝上1500;但是相對的,當我們這些軟體人才都為了生計,最後做的都是這些手機廠所謂的"軟硬體整合"的工作的時候,我們怎麼在雲端運算或是網路服務的這些領域與其它國家相比? 也許最終還是落入一個製造業3%~5%的毛利的競爭,大家都做me too的產品,什麼時候才會有真正的innovation? 什麼時候才會有Internet上或軟體上的競爭力? 對現在的台灣來說,實在太遙遠了...好啦離題了,只是突然有感而發而已。我相信台灣有很多很好的軟體人才,也許再過幾年,會有一些突破性的改變,讓台灣的軟實力能登上國際網台吧! 我期許台灣有一天會變成不只是手機/各式各樣3C產品的製造地,我們也可以很大聲的說,我們也是各種Internet服務的集散地、軟體技術的集散地...(待續)

Sunday, May 15, 2011

One loses for not believing in himself
One loses for dying dreams
One loses for living without an aim
One loses for not knowing his potential
A wellness coach is needed along the way to success
Close your eyes
Open your mind
Never self-limit yourself
Grow to your full potential
You can make it

Friday, April 15, 2011

無止境的學習 (一)



舉個例子,像是strong-typed enum就解決了enum這種C++時代遺留下來、大小不明確的型別。auto跟decltype就解決了很多複雜的nested template(如boost tuple)很難寫出正確的type然後宣告一個變數的問題。把threading放進語言當中我覺得也簡化了很多multi-core的程式設計,以後就不用再用一堆有的沒的3rd party threading library了(雖然目前應該沒有compiler完全實作全部的C++0x threading,我是早就先偷買JustThread來嚐鮮了XD)

除了C/C++之外,這兩年許多新的語言如雨後春筍般的冒出來,也愈來愈多人用,像是Google Go,Scala等等。其實看這些新語言的設計,不難發現這幾年動態語言流行的一些新東西,像是closure、signal/slot、map/reduce的概念都直接built-in到語言中。

在這麼多新語言中,我認為其中Google Go的設計是我最喜歡的,但是他的語法就不是人人都能接受就是了。另外,許多語言都開始想要在語言設計上支援many-core computing,像是erlang的agent或是stackless python tasklet;當然我其實沒那麼多時間把這些語言全部玩過一次,但簡單看一下其實就看的出他的一些特色。

而除了語言之外,因應web 2.0或是新的many-core computing的大趨勢,有許多有趣的framework被開發出來;像是基於server-side javascript的node.js,我個人認為這個實在是個非常有趣的東西,雖然效能不可能跟native code來比,但是他運用了javascript語言的特性,讓http/json server開發變的超簡單,真的很有潛力。

至於many-core computing,像是zeromq的架構我覺得也是非常好的,只要你願意花個幾個小時trace一下zeromq的設計,就不難發現他lock-free network of queues的強大之處,我們甚至自己也重新實做了一個類似的,用來提昇多核心的效能。

對於像我們在做high performance computing跟cluster computing的人來說,一些cluster membership或group communication的middleware也是非常必要的;例如今年OSDC分享的zookeeper(作者居然親自來了),例如RedHat支持的OpenAIS/Corosync等等,我覺得去認真的讀完一些consensus的paper,再回頭看這些分散式系統的實作,也會非常有幫助。

除了language與middleware之外,這幾年compiler的技術也是一日千里。從以前我在學compiler都還在用lex/yacc的時候,進步到現在用一套ANTLR搞定所有AST,甚至是有神人直接用metaprogramming做出boost::spirit跟yardparser,再加上一套general-purpose的LLVM做為universal IR,連optimizer都不用自己做了,這些都實在是五年前完全想像不到的啊! 而且搞不好再過幾年,clang就可以把gcc幹掉了也說不定呢~因為有這些compiler的技術,我自認為寫compiler已經不再是什麼深奧的學問、神祕的技術了。所以套句食神的話:只要有心,人人都可以寫compiler...(待續)

Wednesday, March 02, 2011

People and Faith






...當然「人」還是很重要的啦! 所以我還是回頭講一下我對人的看法。


退而求其次,就是能力不強但是願意相信你的人。咦? 為什麼不是能力不強但是有信念的人呢? 很簡單,因為有信念的人大都對自己很有自信,能力不強但又很有自信的人,自然就會做出一些令人傻眼的事情,而且他們不容易受控制,總覺得自己是對的。反之,能力不強但是願意相信你的人,當他認同你的信念的時候,所能產生出來的力量才會是最強大的。


Tuesday, February 08, 2011

Generalized foreach with C++0x

從別的地方看來的(一時找不太到URL),然後自己加上其它std container的支援以及整數/陣列的支援...個人用了一陣子覺得蠻方便的XD


/* foreach support for non-container type, the indexer iterates through 0 ~ (A-1) */
static inline int8_t beginof(int8_t a) { return 0; }
static inline int8_t endof(int8_t a) { return a; }
static inline uint8_t beginof(uint8_t a) { return 0; }
static inline uint8_t endof(uint8_t a) { return a; }

static inline int16_t beginof(int16_t a) { return 0; }
static inline int16_t endof(int16_t a) { return a; }
static inline uint16_t beginof(uint16_t a) { return 0; }
static inline uint16_t endof(uint16_t a) { return a; }

static inline int32_t beginof(int32_t a) { return 0; }
static inline int32_t endof(int32_t a) { return a; }
static inline uint32_t beginof(uint32_t a) { return 0; }
static inline uint32_t endof(uint32_t a) { return a; }

static inline int64_t beginof(int64_t a) { return 0; }
static inline int64_t endof(int64_t a) { return a; }
static inline uint64_t beginof(uint64_t a) { return 0; }
static inline uint64_t endof(uint64_t a) { return a; }

template static inline T* beginof (T (&a)[N]) { return a; }
template static inline T* endof (T (&a)[N]) { return a + N; }

// foreach support for std::vector
template static inline typename std::vector::iterator beginof (std::vector& v) { return v.begin(); }
template static inline typename std::vector::iterator endof (std::vector& v) { return v.end(); }

template static inline typename std::vector::const_iterator beginof (const std::vector& v) { return v.begin(); }
template static inline typename std::vector::const_iterator endof (const std::vector& v) { return v.end(); }

// foreach support for std::list
template static inline typename std::list::iterator beginof (std::list& v) { return v.begin(); }
template static inline typename std::list::iterator endof (std::list& v) { return v.end(); }

template static inline typename std::list::const_iterator beginof (const std::list& v) { return v.begin(); }
template static inline typename std::list::const_iterator endof (const std::list& v) { return v.end(); }

// foreach support for std::map
template static inline typename std::map::iterator beginof (std::map& m) { return m.begin(); }
template static inline typename std::map::iterator endof (std::map& m) { return m.end(); }

template static inline typename std::map::const_iterator beginof (const std::map& m) { return m.begin(); }
template static inline typename std::map::const_iterator endof (const std::map& m) { return m.end(); }

// foreach support for std::tr1::unordered_set
template static inline typename std::unordered_set::iterator beginof (std::unordered_set& m) { return m.begin(); }
template static inline typename std::unordered_set::iterator endof (std::unordered_set& m) { return m.end(); }

template static inline typename std::unordered_set::const_iterator beginof (const std::unordered_set& m) { return m.begin(); }
template static inline typename std::unordered_set::const_iterator endof (const std::unordered_set& m) { return m.end(); }

template static inline typename std::unordered_map::iterator beginof (std::unordered_map& m) { return m.begin(); }
template static inline typename std::unordered_map::iterator endof (std::unordered_map& m) { return m.end(); }

template static inline typename std::unordered_map::const_iterator beginof (const std::unordered_map& m) { return m.begin(); }
template static inline typename std::unordered_map::const_iterator endof (const std::unordered_map& m) { return m.end(); }
template static inline typename std::tr1::unordered_set::iterator beginof (std::tr1::unordered_set& m) { return m.begin(); }
template static inline typename std::tr1::unordered_set::iterator endof (std::tr1::unordered_set& m) { return m.end(); }

template static inline typename std::tr1::unordered_set::const_iterator beginof (const std::tr1::unordered_set& m) { return m.begin(); }
template static inline typename std::tr1::unordered_set::const_iterator endof (const std::tr1::unordered_set& m) { return m.end(); }

// foreach support for std::tr1::unordered_map
template static inline typename std::tr1::unordered_map::iterator beginof (std::tr1::unordered_map& m) { return m.begin(); }
template static inline typename std::tr1::unordered_map::iterator endof (std::tr1::unordered_map& m) { return m.end(); }

template static inline typename std::tr1::unordered_map::const_iterator beginof (const std::tr1::unordered_map& m) { return m.begin(); }
template static inline typename std::tr1::unordered_map::const_iterator endof (const std::tr1::unordered_map& m) { return m.end(); }

// foreach support for __gnu_cxx::hash_map
template static inline typename __gnu_cxx::hash_map::iterator beginof (__gnu_cxx::hash_map& m) { return m.begin(); }
template static inline typename __gnu_cxx::hash_map::iterator endof (__gnu_cxx::hash_map& m) { return m.end(); }

template static inline typename __gnu_cxx::hash_map::const_iterator beginof (const __gnu_cxx::hash_map& m) { return m.begin(); }
template static inline typename __gnu_cxx::hash_map::const_iterator endof (const __gnu_cxx::hash_map& m) { return m.end(); }

#define foreach(i, c) \
for(decltype(beginof(c)) i = beginof(c); i != endof(c); ++i)

Thursday, January 27, 2011

Git Remote Branch Tracking

當local產生了一個temporary branch
(也就是當初在create branch的時候沒有設tracking..)
從git 1.7之後就有個新的指令(感謝小白~)

$ git branch --set-upstream [branch_name] origin/[branch_name]


Autojump with Profile Switch

當autojump用到走火入魔的地步的時候...你就會需要profile switch了!
也就是說我希望在不同的情況下, 某一個keyword會到不同的目錄!!

if [ "$#" -gt "0" ]; then
if [ -d ~/.local/share/autojump_$1 ]; then
rm -fr ~/.local/share/autojump
ln -s ~/.local/share/autojump_$1 ~/.local/share/autojump
echo "changed autojump profile to \"$1\""
read -N 1 -p "profile \"$1\" does not exist, create it? (y/n)"
if [ "$REPLY" == "y" ]; then
mkdir ~/.local/share/autojump_$1
rm -fr ~/.local/share/autojump
ln -s ~/.local/share/autojump_$1 ~/.local/share/autojump
echo -e "\nchanged autojump profile to \"$1\""
echo -e ""
echo "Usage: ajcp [profile_name]"
echo ""
echo "Change to given autojump profile."