diff --git a/Dockerfile b/Dockerfile index 0d2f56911442f989c0abfa8fdea924af1be48f9e..dc443887323b4cd1419272405b15f3ddb19f88d1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -29,7 +29,7 @@ RUN apt-get update && \ curl sed grep graphviz libjpeg-dev zlib1g-dev \ python-numpy python-matplotlib gcc g++ \ automake locales clang-format-3.8 swig doxygen cmake \ - liblapack-dev liblapacke-dev \ + liblapack-dev liblapacke-dev libboost-dev \ clang-3.8 llvm-3.8 libclang-3.8-dev && \ apt-get clean -y @@ -61,6 +61,15 @@ RUN git clone https://github.com/woboq/woboq_codebrowser /woboq && \ -DCMAKE_BUILD_TYPE=Release . \ make) +# Install gtest. +# +# NOTE: This is added for quick hack of the development work of +# majel-in-paddle. +RUN git clone https://github.com/google/googletest /gtest && \ + cd /gtest && \ + git checkout -b release-1.8.0 && \ + cmake . && make install + # Configure OpenSSH server. c.f. https://docs.docker.com/engine/examples/running_ssh_service RUN mkdir /var/run/sshd RUN echo 'root:root' | chpasswd diff --git a/majel/Makefile b/majel/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..403c1d3a6ae81fddd6f89977fe930211334156b8 --- /dev/null +++ b/majel/Makefile @@ -0,0 +1,10 @@ +CCFLAGS = -std=c++11 -I/work/paddle +CC = nvcc + +all : place_test + +place.o : place.h place.cu + $(CC) $(CCFLAGS) -c place.cu -o $@ + +place_test : place.o place_test.cu + $(CC) $(CCFLAGS) -lgtest -lgtest_main $^ -o $@ diff --git a/majel/place.cu b/majel/place.cu new file mode 100644 index 0000000000000000000000000000000000000000..ee84e96048d549a3e87bca6712702105a904de71 --- /dev/null +++ b/majel/place.cu @@ -0,0 +1,61 @@ +#include + +namespace majel { + +namespace detail { + +class PlacePrinter + : public boost::static_visitor<> { +private: + std::ostream& os_; +public: + PlacePrinter(std::ostream& os) : os_(os) {} + + void operator()(const CpuPlace&) { + os_ << "CpuPlace"; + } + + void operator()(const GpuPlace& p) { + os_ << "GpuPlace(" << p.device << ")"; + } +}; + +} // namespace majel + +static Place the_default_place; + +void set_place(const Place& place) { + the_default_place = place; +} + +const Place& get_place() { + return the_default_place; +} + +const GpuPlace default_gpu() { + return GpuPlace(0); +} + +const CpuPlace default_cpu() { + return CpuPlace(); +} + +bool is_gpu_place(const Place& p) { + return boost::apply_visitor(IsGpuPlace(), p); +} + +bool is_cpu_place(const Place& p) { + return !boost::apply_visitor(IsGpuPlace(), p); +} + +bool places_are_same_class(const Place& p1, const Place& p2) { + return is_gpu_place(p1) == is_gpu_place(p2); +} + +std::ostream& operator<<(std::ostream& os, const majel::Place& p) { + majel::detail::PlacePrinter printer(os); + boost::apply_visitor(printer, p); + return os; +} + +} // namespace majel diff --git a/majel/place.h b/majel/place.h new file mode 100644 index 0000000000000000000000000000000000000000..ad3dc3fe0b80ac5dc10a59910c580d7912469cd4 --- /dev/null +++ b/majel/place.h @@ -0,0 +1,50 @@ +#pragma once +#include +#include + +namespace majel { + +struct CpuPlace { + CpuPlace() {} // WORKAROUND: for some reason, omitting this constructor + // causes errors with boost 1.59 and OSX + // needed for variant equality comparison + inline bool operator==(const CpuPlace&) const { return true; } + + inline bool operator!=(const CpuPlace&) const { return false; } +}; + +struct GpuPlace { + GpuPlace(int d) : device(d) {} + + // needed for variant equality comparison + inline bool operator==(const GpuPlace& o) const { return device == o.device; } + + inline bool operator!=(const GpuPlace& o) const { return !(*this == o); } + + GpuPlace() : GpuPlace(0) {} + int device; +}; + +class IsGpuPlace : public boost::static_visitor { +public: + bool operator()(const CpuPlace&) const { return false; } + + bool operator()(const GpuPlace& gpu) const { return true; } +}; + +typedef boost::variant Place; + +void set_place(const Place&); + +const Place& get_place(); + +const GpuPlace default_gpu(); +const CpuPlace default_cpu(); + +bool is_gpu_place(const Place&); +bool is_cpu_place(const Place&); +bool places_are_same_class(const Place&, const Place&); + +std::ostream& operator<<(std::ostream&, const majel::Place&); + +} // namespace majel diff --git a/majel/place_test.cu b/majel/place_test.cu new file mode 100644 index 0000000000000000000000000000000000000000..cb8294613037850727817a87f12bd93744f178c5 --- /dev/null +++ b/majel/place_test.cu @@ -0,0 +1,40 @@ +#include "gtest/gtest.h" +#include "majel/place.h" +#include + +TEST(Place, Equality) { + majel::CpuPlace cpu; + majel::GpuPlace g0(0), g1(1), gg0(0); + + EXPECT_EQ(cpu, cpu); + EXPECT_EQ(g0, g0); + EXPECT_EQ(g1, g1); + EXPECT_EQ(g0, gg0); + + EXPECT_NE(g0, g1); + + EXPECT_TRUE(majel::places_are_same_class(g0, gg0)); + EXPECT_FALSE(majel::places_are_same_class(g0, cpu)); +} + +TEST(Place, Default) { + EXPECT_TRUE(majel::is_gpu_place( majel::get_place())); + EXPECT_TRUE(majel::is_gpu_place( majel::default_gpu())); + EXPECT_TRUE(majel::is_cpu_place( majel::default_cpu())); + + majel::set_place(majel::CpuPlace()); + EXPECT_TRUE(majel::is_cpu_place( majel::get_place())); +} + +TEST(Place, Print) { + { + std::stringstream ss; + ss << majel::GpuPlace(1); + EXPECT_EQ("GpuPlace(1)", ss.str()); + } + { + std::stringstream ss; + ss << majel::CpuPlace(); + EXPECT_EQ("CpuPlace", ss.str()); + } +}