From db4ab76009a645e8f83b6f1faa62c2156541e084 Mon Sep 17 00:00:00 2001 From: lemoinep Date: Mon, 25 Sep 2023 17:13:26 +0200 Subject: [PATCH] Update Src Code Cmakefiles for Cuda --- .../assets/images/domain-decomposition.svg | 302 +++++++ docs/modules/ROOT/assets/images/eq1.png | Bin 0 -> 942 bytes docs/modules/ROOT/assets/images/eq2.png | Bin 0 -> 2772 bytes docs/modules/ROOT/assets/images/eq3.png | Bin 0 -> 1400 bytes docs/modules/ROOT/assets/images/eq4.png | Bin 0 -> 1221 bytes docs/modules/ROOT/pages/HEAT_Coding.adoc | 91 +++ docs/modules/ROOT/pages/index.adoc | 5 + src/CMakeLists.txt | 7 +- src/Cuda/DynamicSync/CMakeLists.txt | 103 +++ .../Cuda/CMakeLists.txt | 103 +++ .../Cuda/{Makefile => OldMakefile} | 0 .../MPI/CMakeLists.txt | 56 +- .../MPI/pngwriter.h | 739 ------------------ .../MPI_OpenMP/CMakeLists.txt | 62 +- .../MPI_OpenMP/{MakefileOld => OldMakefile} | 0 .../common/pngwriter.c | 221 ++++++ .../common/pngwriter.h | 14 + src/Tools/mpi_cuda_awareness_check.cpp | 44 ++ 18 files changed, 954 insertions(+), 793 deletions(-) create mode 100644 docs/modules/ROOT/assets/images/domain-decomposition.svg create mode 100644 docs/modules/ROOT/assets/images/eq1.png create mode 100644 docs/modules/ROOT/assets/images/eq2.png create mode 100644 docs/modules/ROOT/assets/images/eq3.png create mode 100644 docs/modules/ROOT/assets/images/eq4.png create mode 100644 docs/modules/ROOT/pages/HEAT_Coding.adoc create mode 100644 src/Cuda/DynamicSync/CMakeLists.txt create mode 100644 src/Heat_Equation_ParallelPrograming_Comparison/Cuda/CMakeLists.txt rename src/Heat_Equation_ParallelPrograming_Comparison/Cuda/{Makefile => OldMakefile} (100%) delete mode 100644 src/Heat_Equation_ParallelPrograming_Comparison/MPI/pngwriter.h rename src/Heat_Equation_ParallelPrograming_Comparison/MPI_OpenMP/{MakefileOld => OldMakefile} (100%) create mode 100644 src/Heat_Equation_ParallelPrograming_Comparison/common/pngwriter.c create mode 100644 src/Heat_Equation_ParallelPrograming_Comparison/common/pngwriter.h create mode 100644 src/Tools/mpi_cuda_awareness_check.cpp diff --git a/docs/modules/ROOT/assets/images/domain-decomposition.svg b/docs/modules/ROOT/assets/images/domain-decomposition.svg new file mode 100644 index 0000000..2820845 --- /dev/null +++ b/docs/modules/ROOT/assets/images/domain-decomposition.svg @@ -0,0 +1,302 @@ + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + Rank #0 + Rank #1 + Rank #2 + Rank #3 + Local + of the + portion + grid + + + + + + + + + ghost-layer + ghost-layer + ghost-layer + ghost-layer + ghost-layer + ghost-layer + + diff --git a/docs/modules/ROOT/assets/images/eq1.png b/docs/modules/ROOT/assets/images/eq1.png new file mode 100644 index 0000000000000000000000000000000000000000..ce6357073b95dc6d9ac9703aa247d9de45a459da GIT binary patch literal 942 zcmeAS@N?(olHy`uVBq!ia0vp^p+GFo!2%>NNn{1`6_P!I zd>I(3)EF2VS{N990fib~Fff!FFfhDIU|_JC0n}eGXIG#NP=YDR+ueoXe|!I#{XiaP zfk$L90|Va?5N4dJ%_j{MWH0gbb!C6bAuJ}LfAYc0$3RWRo-U3d9>>p4yIpwOK*05U zRSd%-KBw{nM`RDkDoo~LDrJ~DA<=4qH^*JZyN*uf4y6KtvN?7KmaCkS>)yy*BfzZJ z(A~Y8KakY_U@#Fkv-S76;~r?=`@&w*KoEk3u#%&(d~DMsFJ z{r8Z)LEYctKHe^oit7nAPTeq9_9we!U76{$O?Q{61d7uhW>_L|Q+A$Z;k z_w#NSHLy`pV0cy+>pIz4G3j0{vke#k+D!W$*58wfST4cy|1W%u9`dB3i4I_qv7KNpD}d zI9Pbm*HY=TK|-|?LN@8ypH1Oea$wF3y|2erJ{xq->t{E;-4+w1^Yf;`9D&7eW&IV_ z?RLCr-Iy<-dy*-E`uwQw(GAJ?-V$?MgNJ1=hD^T%I%MKTsHMMeEjm7eFplf zIV)~#e59^zR99$!&)=rgOD*zW|ru4TV^QB;TX{?D%T;x9SfW}fXSzYbmd zb!$aJ;D`6&Jo7|ZP6|v45NfS?*|JOI%HyV`ak~N{7sWG1mtEW%A?$qB>-(c4f2^18 z^SaCBk-$IWoVV)ol>Iqtt15qU*FOs~|8f1A88AgEmAFQfB9cfU<`wNOekLNvc(HQ7VvPFfuSQ)HSfsHM9&dGO{u< su`)5&Hn6lZFjz9t{yEl1!`dMboFyt=akR{05GA3pa1{> literal 0 HcmV?d00001 diff --git a/docs/modules/ROOT/assets/images/eq2.png b/docs/modules/ROOT/assets/images/eq2.png new file mode 100644 index 0000000000000000000000000000000000000000..2843fab48e0f711555fe755aa1f7e0553fcf8584 GIT binary patch literal 2772 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 x+9LxI2o%B*b literal 0 HcmV?d00001 diff --git a/docs/modules/ROOT/assets/images/eq4.png b/docs/modules/ROOT/assets/images/eq4.png new file mode 100644 index 0000000000000000000000000000000000000000..f94c8093956d3531e777a5899d8e131cf1355046 GIT binary patch literal 1221 zcmeAS@N?(olHy`uVBq!ia0vp^-9RkQ!2%>}pMO&XQY`6?zK#qG8~eHcB(ehe3dtTp zz6=aiY77hwEes65fICD#?XB&vL z+NTCJq%|=vi{?n5oIC&BjI(aCWebe|>0J8D?tkjoG1oxT z`^UaN)Hxq*^8Hh-W8a%Y)$`t5=6u~WZ_cD$|D_$K)|O1DTybrw@H6Hs(_+(B8eHBg z=j&oFdN%05C9dR4F^e=VY?)!VQ*B$b!?Dgjy^Y&`O#Oc_E%VOq9hbZha@u~Aes#Lz zQ{bV9kW3q8ckL^SwrQMpd^y$TdiMQ$KW1okUy@lqrT*aw{|UwnZQ(EO=kl^@Juh|m zH*dyyPXGCpD_mpvs_x5g)B47{c&Uu^+eN<8EWJyWo<9jn=QUO1w`8xMrkVdrPuG&S zD6-|+zUYNrNo6xt->+u8d8*&EZ4#69wi~5W8kQZqR5ew#{CZ~EO7>r_dlI&BUCt3Y z8#O1^#^=3(PgD3}nW%^>E45A@ja!qlxA4!60|6H=2IejoY@4QKmdGROGc4T|K{aGq&*Q}%Ujg@94*C7@()HiniI%Zm0bZGq0F*EBj{p*PhUsGIwu1cx3VE zPmI+uHNB^pT=^w<(RW>H)Ui`WaTyz#Zmkuv4RMv$?w0WKn$_}cuX8NtYqkI9 zS{z(GH(Ky}_@8AI)(V}Xc)2HfOU2~-%h$D(O#Ytms(o#L21{d8R?fZISGM)9yxLwC z{HJyAw&2*C*L?3aYYN?XsXnc&`jKALhKN($Th2b~c3g8nGvtcl<+__^dOqp-yic3f zak0&1vDCIdXOoPsuh3q-%X5mRXXDQPz*U*gi)O{G`(#|Vf7hm^vs-2ciO#5&Si0ba z`J}%`*#4jWR0|bvF=2i7ENY#R&B^XdHSEhfKD2I^%vrvRDd(k{3p!sW$_k9>a2SE{O$(K6$bh=gi?-=vxP?ejhtEZhHT ztxjy#s$WXLjH*=P8c~v*pPQSSSHcjKnwOGVl$xTDRH+bHnwgyKlNgd3p$C*!@Vu}M zs9F`IIwi3r)hf9t6-Y4{85kMr8d&NY7={>HSOJlVp|*jgm4Sic|CduyH00)|WTsW( V))25LP!p(u!PC{xWt~$(698|g8T0@E literal 0 HcmV?d00001 diff --git a/docs/modules/ROOT/pages/HEAT_Coding.adoc b/docs/modules/ROOT/pages/HEAT_Coding.adoc new file mode 100644 index 0000000..0bebc54 --- /dev/null +++ b/docs/modules/ROOT/pages/HEAT_Coding.adoc @@ -0,0 +1,91 @@ += Heat Equation Parallel Programming Comparison + + + +.Heat equation in 2D +[.examp] +**** + +* Theory + +Heat (or diffusion) equation is a partial differential equation that describes the variation of temperature in a given region over time + + +\begin{align*} +\frac{\partial u}{\partial t} = \alpha \nabla^2 u +\end{align*} + + +image::eq1.png[Img901] + +where *u*(*x*, *y*, *t*) is the temperature field that varies in space and +time, and α is the thermal diffusivity constant. + +We limit ourselvels to two dimensions (a plane) where Laplacian can be +discretized in a grid with finite differences as + + +\begin{align*} +\nabla^2 u &= \frac{u(i-1,j)-2u(i,j)+u(i+1,j)}{(\Delta x)^2} \\ + &+ \frac{u(i,j-1)-2u(i,j)+u(i,j+1)}{(\Delta y)^2} +\end{align*} + +where ∆x and ∆y are the grid spacing of the temperature grid *u*. + +Given an initial condition (*u*(t=0) = u0) one can follow the time dependence +of the temperature field with explicit time evolution method: + +\begin{align*} +u^{m+1}(i,j) = u^m(i,j) + \Delta t \alpha \nabla^2 u^m(i,j) +\end{align*} + + +Note: The algorithm is stable only when + +\begin{align*} +\Delta t < \frac{1}{2 \alpha} \frac{(\Delta x \Delta y)^2}{(\Delta x)^2 (\Delta y)^2} +\end{align*} + +**** + + + +.Code +[.examp] +**** +The solver carries out the time development of the 2D heat equation over the number of time steps provided by the user. The default geometry is a flat +rectangle (with grid size provided by the user), but other shapes may be used via input files. The program will produce an image (PNG) of the temperature field after every 100 iterations. + +.Heat equation solver with MPI +[source,cpp] +---- +include::ROOT:example$src/Heat_Equation_ParallelPrograming_Comparison/MPI/main.cpp[indent=0] +---- + +.Heat equation solver with hybrid MPI+OpenMP +[source,cpp] +---- +include::ROOT:example$src/Heat_Equation_ParallelPrograming_Comparison/MPI_OpenMP/main.cpp[indent=0] +---- + + +.Heat equation solver with Cuda +[source,cu] +---- +include::ROOT:example$src/Heat_Equation_ParallelPrograming_Comparison/Cuda/core_cuda.cu[indent=0] +---- +**** + +.*Performance* +**** +ADD SOME RESULTS +**** + + + + + + + +... + diff --git a/docs/modules/ROOT/pages/index.adoc b/docs/modules/ROOT/pages/index.adoc index 5266b7c..e547972 100644 --- a/docs/modules/ROOT/pages/index.adoc +++ b/docs/modules/ROOT/pages/index.adoc @@ -246,4 +246,9 @@ image::ParallelProgramming1.jpeg[Img3,400,400] * xref:SPECX_Coding.adoc[SPECX Coding] **** +.Case Studies +[.examp] +**** +* xref:HEAT_Coding.adoc[Case Study Heat Coding] +**** diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7a05da0..43ea940 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -60,8 +60,11 @@ if(FALSE) add_subdirectory(CUDA/Parallelism_Reduction) add_subdirectory(CUDA/SimpleStreams) add_subdirectory(CUDA/Start) - add_subdirectory(CUDA/Task_Paralllism) - add_subdirectory(CUDA/Vector) + add_subdirectory(CUDA/Task_Paralllism/Async1) + add_subdirectory(CUDA/Task_Paralllism/Async2) + add_subdirectory(CUDA/Vector/MatrixAdd) + add_subdirectory(CUDA/Vector/VectorAdd) + add_subdirectory(CUDA/Vector/VectorDotProduct) endif() #END:CUDA PART diff --git a/src/Cuda/DynamicSync/CMakeLists.txt b/src/Cuda/DynamicSync/CMakeLists.txt new file mode 100644 index 0000000..2dcbaa6 --- /dev/null +++ b/src/Cuda/DynamicSync/CMakeLists.txt @@ -0,0 +1,103 @@ + +#project(MPI_bcast) + +######## A simple cmakelists.txt file for ... ############# + +cmake_minimum_required(VERSION 3.17) +#set(CMAKE_CXX_STANDARD 14) +#set(CMAKE_BUILD_TYPE Debug) +set(CMAKE_BUILD_TYPE Release) +#set(CMAKE_CXX_COMPILER "/usr/local/bin/g++") +#set(CMAKE_CXX_STANDARD 14) +#set(CMAKE_CXX_COMPILER "/usr/local/bin/g++") +#set(CMAKE_C_COMPILER "/usr/bin/clang-14") +#set(CMAKE_CXX_COMPILER "/usr/bin/clang++-14") +#set(CMAKE_CXX_COMPILER "/usr/bin/gcc") +#set(CMAKE_CXX_COMPILER "/usr/bin/g++-11") + + + +if(FALSE) + find_package(MPI REQUIRED) + if (MPI_FOUND) + MESSAGE("{MPI_CXX_LIBRARIES}") + else (MPI_FOUND) + MESSAGE (SEND_ERROR "This application cannot compile without MPI") + endif(MPI_FOUND) +endif() + + +if(FALSE) + find_package(OpenMP) + if (OpenMP_CXX_FOUND) + MESSAGE("{OpenMP_CXX_LIBRARIES}") + else (OpenMP_CXX_FOUND) + MESSAGE (SEND_ERROR "This application cannot compile without OpenMPI") + endif(OpenMP_CXX_FOUND) +endif() + + +find_package(CUDA REQUIRED) + +if (CUDA_FOUND) + MESSAGE("{CUDA_CXX_LIBRARIES}") + else (CUDA_FOUND) + MESSAGE (SEND_ERROR "This application cannot compile without CUDA") + endif(CUDA_FOUND) + +add_definitions(-D_FORCE_INLINES) + +#set (CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} --gpu-architecture sm_21 -std=c++11) + +set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS}; -O3 ) + +file(GLOB WFOPenMP_SRC + "*.cu" +) + +foreach (myfile ${WFOPenMP_SRC}) + get_filename_component(myname ${myfile} NAME_WLE) + get_filename_component(dirname ${myfile} DIRECTORY) + message("${myname}.cu | ${dir_src}") + #add_executable(${myname} "${myname}.c") + + cuda_add_executable(${myname} "${myname}.cu") + + #target_link_libraries( ${myname} -lfoobar -ljoestuff ) + + #if(MPI_FOUND) + #include_directories(SYSTEM ${MPI_INCLUDES_PATH}) + #target_include_directories(${myname} PUBLIC ${MPI_CXX_INCLUDE_DIRS}) + #target_link_libraries(${myname} PUBLIC ${MPI_CXX_LIBRARIES} ) + #endif() + + +endforeach (file ${WFOPenMP_SRC}) + + +if(FALSE) + file(GLOB WFOPenMP_SRC + "*.cpp" + "*.h" + ) + + foreach (myfile ${WFOPenMP_SRC}) + get_filename_component(myname ${myfile} NAME_WLE) + get_filename_component(dirname ${myfile} DIRECTORY) + message("${myname}.cpp | ${dir_src}") + #add_executable(${myname} "${myname}.c") + + cuda_add_executable(${myname} "${myname}.cpp") + + #target_link_libraries( ${myname} -lfoobar -ljoestuff ) + + #if(MPI_FOUND) + #include_directories(SYSTEM ${MPI_INCLUDES_PATH}) + #target_include_directories(${myname} PUBLIC ${MPI_CXX_INCLUDE_DIRS}) + #target_link_libraries(${myname} PUBLIC ${MPI_CXX_LIBRARIES} ) + #endif() + endforeach (file ${WFOPenMP_SRC}) +endif() + + +########### end #################################### diff --git a/src/Heat_Equation_ParallelPrograming_Comparison/Cuda/CMakeLists.txt b/src/Heat_Equation_ParallelPrograming_Comparison/Cuda/CMakeLists.txt new file mode 100644 index 0000000..b4156c6 --- /dev/null +++ b/src/Heat_Equation_ParallelPrograming_Comparison/Cuda/CMakeLists.txt @@ -0,0 +1,103 @@ +project(HEATDemoCuda) + +######## A simple cmakelists.txt file for Open... ############# +#cmake_minimum_required(VERSION 3.26) +cmake_minimum_required(VERSION 3.17) +#set(CMAKE_CXX_STANDARD 14) +set(CMAKE_BUILD_TYPE Debug) +#set(CMAKE_BUILD_TYPE Release) +#set(CMAKE_CXX_COMPILER "/usr/local/bin/g++") +#set(CMAKE_CXX_STANDARD 14) +#set(CMAKE_CXX_COMPILER "/usr/local/bin/g++") +#set(CMAKE_C_COMPILER "/usr/bin/clang-14") +#set(CMAKE_CXX_COMPILER "/usr/bin/clang++-14") +#set(CMAKE_CXX_COMPILER "/usr/bin/gcc") +#set(CMAKE_CXX_COMPILER "/usr/bin/g++-11") + + +include_directories("../common") + + + +if(TRUE) + find_package(MPI REQUIRED) + if (MPI_FOUND) + MESSAGE("{MPI_CXX_LIBRARIES}") + else (MPI_FOUND) + MESSAGE (SEND_ERROR "This application cannot compile without MPI") + endif(MPI_FOUND) +endif() + +if(FALSE) + find_package(OpenMP) + if (OpenMP_CXX_FOUND) + MESSAGE("{OpenMP_CXX_LIBRARIES}") + else (OpenMP_CXX_FOUND) + MESSAGE (SEND_ERROR "This application cannot compile without OpenMP") + endif(OpenMP_CXX_FOUND) +endif() + + +find_package(CUDA REQUIRED) + +if (CUDA_FOUND) + MESSAGE("{CUDA_CXX_LIBRARIES}") + MESSAGE(STATUS "Found headers CUDA : ${CUDA_INCLUDE_DIRS}") + MESSAGE(STATUS "Found lib CUDA : ${CUDA_LIBRARIES}") + MESSAGE(STATUS "Found CUDA nvcc : ${CUDA_NVCC_EXECUTABLE}") + else (CUDA_FOUND) + MESSAGE (SEND_ERROR "This application cannot compile without CUDA") + endif(CUDA_FOUND) + +add_definitions(-D_FORCE_INLINES) + +#set (CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} --gpu-architecture sm_21 -std=c++11) + +set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS}; -O3 ) + +find_package(PNG REQUIRED) +if (PNG_FOUND) + MESSAGE("{PNG_LIBRARIES}") + else (PNG_FOUND) + MESSAGE (SEND_ERROR "This application cannot compile without PNG") + endif(PNG_FOUND) + + +#file(GLOB my_cpp_list "${CMAKE_CURRENT_SOURCE_DIR}/common/*.c") +file(GLOB my_common_list + "${CMAKE_CURRENT_SOURCE_DIR}/../common/*.c" + "${CMAKE_CURRENT_SOURCE_DIR}/../common/*.h" +) + +if (FALSE) + message(${CMAKE_CURRENT_SOURCE_DIR}) + foreach(file_path ${my_cpp_list} ${my_common_list}) + message(${file_path}) + endforeach() +endif() + + +file(GLOB All_SRC + "*.h" + "*.cpp" + "*.cu" +) + + +#add_executable(HEATDemoCuda main.cpp ${All_SRC} ${my_common_list}) + +cuda_add_executable(HEATDemoCuda ${All_SRC} ${my_common_list}) + +include_directories(SYSTEM ${MPI_INCLUDES_PATH}) +target_include_directories(HEATDemoCuda PUBLIC ${MPI_CXX_INCLUDE_DIRS} ${PNG_INCLUDE_DIR} ${CUDA_INCLUDE_DIRS}) +#target_link_libraries(HEATDemoCuda PUBLIC ${MPI_CXX_LIBRARIES} ${PNG_LIBRARY} PUBLIC cuda) +#cuda_add_library(HEATDemoCuda PUBLIC ${MPI_CXX_LIBRARIES} ${PNG_LIBRARY} ) +#add_library(HEATDemoCuda PUBLIC ${MPI_CXX_LIBRARIES} ${PNG_LIBRARY}) + +#target_link_libraries(HEATDemoCuda PUBLIC ${MPI_CXX_LIBRARIES} ${PNG_LIBRARY} ${CUDA_LIBRARIES}) + +target_link_libraries(HEATDemoCuda ${MPI_CXX_LIBRARIES}) +target_link_libraries(HEATDemoCuda ${PNG_LIBRARY}) +#target_link_libraries(HEATDemoCuda ${CUDA_LIBRARIES}) + + diff --git a/src/Heat_Equation_ParallelPrograming_Comparison/Cuda/Makefile b/src/Heat_Equation_ParallelPrograming_Comparison/Cuda/OldMakefile similarity index 100% rename from src/Heat_Equation_ParallelPrograming_Comparison/Cuda/Makefile rename to src/Heat_Equation_ParallelPrograming_Comparison/Cuda/OldMakefile diff --git a/src/Heat_Equation_ParallelPrograming_Comparison/MPI/CMakeLists.txt b/src/Heat_Equation_ParallelPrograming_Comparison/MPI/CMakeLists.txt index dca7817..fba8225 100644 --- a/src/Heat_Equation_ParallelPrograming_Comparison/MPI/CMakeLists.txt +++ b/src/Heat_Equation_ParallelPrograming_Comparison/MPI/CMakeLists.txt @@ -1,8 +1,7 @@ +project(HEATDemoMPI) -#project(MPI_bcast) - -######## A simple cmakelists.txt file for ... ############# - +######## A simple cmakelists.txt file for Open... ############# +#cmake_minimum_required(VERSION 3.26) cmake_minimum_required(VERSION 3.17) #set(CMAKE_CXX_STANDARD 14) #set(CMAKE_BUILD_TYPE Debug) @@ -15,18 +14,12 @@ set(CMAKE_BUILD_TYPE Release) #set(CMAKE_CXX_COMPILER "/usr/bin/gcc") #set(CMAKE_CXX_COMPILER "/usr/bin/g++-11") -if(TRUE) - find_package(PNGwriter) - if(PNGwriter_FOUND) - MESSAGE("{PNGwrite_LIBRARIES}") - else (PNGwriter_FOUND) - MESSAGE(SEND_ERROR "{PNGwrite_LIBRARIES Not Found}") - endif(PNGwriter_FOUND) -endif() +include_directories("../common") -if(FALSE) + +if(TRUE) find_package(MPI REQUIRED) if (MPI_FOUND) MESSAGE("{MPI_CXX_LIBRARIES}") @@ -40,26 +33,41 @@ if(FALSE) if (OpenMP_CXX_FOUND) MESSAGE("{OpenMP_CXX_LIBRARIES}") else (OpenMP_CXX_FOUND) - MESSAGE (SEND_ERROR "This application cannot compile without OpenMPI") + MESSAGE (SEND_ERROR "This application cannot compile without OpenMP") endif(OpenMP_CXX_FOUND) endif() -file(GLOB SOURCES - "*.h" - "*.cpp" -) +find_package(PNG REQUIRED) +if (PNG_FOUND) + MESSAGE("{PNG_LIBRARIES}") + else (PNG_FOUND) + MESSAGE (SEND_ERROR "This application cannot compile without PNG") + endif(PNG_FOUND) -add_executable(HeatMPI ${SOURCES}) -include_directories(SYSTEM ${MPI_INCLUDES_PATH}) -target_include_directories(HeatMPI PUBLIC ${MPI_CXX_INCLUDE_DIRS}) -target_link_libraries(HeatMPI PUBLIC ${MPI_CXX_LIBRARIES} PRIVATE PNGwriter::PNGwriter ) -#target_link_libraries(HeatMPI PUBLIC ${MPI_CXX_LIBRARIES} PRIVATE libPNGwrite.a) +#file(GLOB my_cpp_list "${CMAKE_CURRENT_SOURCE_DIR}/common/*.c") +file(GLOB my_common_list + "${CMAKE_CURRENT_SOURCE_DIR}/../common/*.c" + "${CMAKE_CURRENT_SOURCE_DIR}/../common/*.h" +) + +message(${CMAKE_CURRENT_SOURCE_DIR}) +foreach(file_path ${my_cpp_list} ${my_common_list}) + message(${file_path}) +endforeach() +file(GLOB All_SRC + "*.h" + "*.cpp" + "*.c" +) +add_executable(HEATDemoMPI main.cpp ${All_SRC} ${my_common_list}) +include_directories(SYSTEM ${MPI_INCLUDES_PATH}) +target_include_directories(HEATDemoMPI PUBLIC ${MPI_CXX_INCLUDE_DIRS} ${PNG_INCLUDE_DIR}) +target_link_libraries(HEATDemoMPI PUBLIC ${MPI_CXX_LIBRARIES} ${PNG_LIBRARY}) -########### end #################################### diff --git a/src/Heat_Equation_ParallelPrograming_Comparison/MPI/pngwriter.h b/src/Heat_Equation_ParallelPrograming_Comparison/MPI/pngwriter.h deleted file mode 100644 index 63c5d71..0000000 --- a/src/Heat_Equation_ParallelPrograming_Comparison/MPI/pngwriter.h +++ /dev/null @@ -1,739 +0,0 @@ -/********************************* PNGwriter ********************************** -* -* Website: Main: http://pngwriter.sourceforge.net/ -* GitHub.com: https://github.com/pngwriter/pngwriter -* Sourceforge.net: http://sourceforge.net/projects/pngwriter/ -* -* -* Author: Paul Blackburn https://github.com/individual61 -* Axel Huebl https://github.com/ax3l -* -* Email: individual61@users.sourceforge.net -* -* Version: 0.7.0 (January 2018) -* -* Description: Library that allows plotting a 48 bit -* PNG image pixel by pixel, which can -* then be opened with a graphics program. -* -* License: GNU General Public License -* (C) 2002-2018 Paul Blackburn -* (C) 2013-2018 Axel Huebl -* -******************************************************************************/ - - -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * */ - -#ifndef PNGWRITER_H -#define PNGWRITER_H 1 - -#define PNGWRITER_VERSION_MAJOR 0 -#define PNGWRITER_VERSION_MINOR 7 -#define PNGWRITER_VERSION_PATCH 0 - -/* deprecated old define in style MAJOR.MINORREVISION, e.g., 0.56 for 0.5.6 */ -#define PNGWRITER_PASTE(x,y,z) x ## . ## y ## z -#define PNGWRITER_EVALUATE(x,y,z) PNGWRITER_PASTE(x,y,z) -#define PNGWRITER_VERSION PNGWRITER_EVALUATE(PNGWRITER_VERSION_MAJOR, PNGWRITER_VERSION_MINOR, PNGWRITER_VERSION_PATCH) - -/* includes */ -#include -#if (PNG_LIBPNG_VER >= 10500) -#include -#endif - -// REMEMBER TO ADD -DNO_FREETYPE TO YOUR COMPILATION FLAGS IF PNGwriter WAS -// COMPILED WITHOUT FREETYPE SUPPORT!!! -// -// must be included before FreeType headers. -#ifndef NO_FREETYPE -#include -#include FT_FREETYPE_H -#endif - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - - -#define PNG_BYTES_TO_CHECK (4) -#define PNGWRITER_DEFAULT_COMPRESSION (6) - -class pngwriter -{ - private: - - std::string filename_; - std::string textauthor_; - std::string textdescription_; - std::string texttitle_; - std::string textsoftware_; - - - - int height_; - int width_; - int backgroundcolour_; - int bit_depth_; - int colortype_; - int compressionlevel_; - bool transformation_; // Required by Mikkel's patch - - unsigned char * * graph_; - double filegamma_; - double screengamma_; - void circle_aux(int xcentre, int ycentre, int x, int y, int red, int green, int blue); - void circle_aux_blend(int xcentre, int ycentre, int x, int y, double opacity, int red, int green, int blue); - int static check_if_png(char *file_name, FILE **fp); - int static read_png_info(FILE *fp, png_structp *png_ptr, png_infop *info_ptr); - int static read_png_image(FILE *fp, png_structp png_ptr, png_infop info_ptr, - png_bytepp *image, png_uint_32& width, png_uint_32& height); - void flood_fill_internal( int xstart, int ystart, double start_red, double start_green, double start_blue, double fill_red, double fill_green, double fill_blue); - void flood_fill_internal_blend( int xstart, int ystart, double opacity, double start_red, double start_green, double start_blue, double fill_red, double fill_green, double fill_blue); - -#ifndef NO_FREETYPE - void my_draw_bitmap( FT_Bitmap * bitmap, int x, int y, double red, double green, double blue); - void my_draw_bitmap_blend( FT_Bitmap * bitmap, int x, int y,double opacity, double red, double green, double blue); -#endif - - /* The algorithms HSVtoRGB and RGBtoHSV were found at http://www.cs.rit.edu/~ncs/ - * which is a page that belongs to Nan C. Schaller, though - * these algorithms appear to be the work of Eugene Vishnevsky. - * */ - void static HSVtoRGB( double *r, double *g, double *b, double h, double s, double v ); - void static RGBtoHSV( float r, float g, float b, float *h, float *s, float *v ); - - /* drwatop(), drawbottom() and filledtriangle() were contributed by Gurkan Sengun - * ( , http://www.linuks.mine.nu/ ) - * */ - void drawtop(long x1,long y1,long x2,long y2,long x3, int red, int green, int blue); - void drawbottom(long x1,long y1,long x2,long x3,long y3, int red, int green, int blue); - void drawbottom_blend(long x1,long y1,long x2,long x3,long y3, double opacity, int red, int green, int blue); - void drawtop_blend(long x1,long y1,long x2,long y2,long x3, double opacity, int red, int green, int blue); - - /* free up memory of member variables and reset internal pointers to NULL */ - void deleteMembers(); - public: - - /* General Notes - * It is important to remember that all functions that accept an argument of type "const char *" will also - * accept "char *", this is done so you can have a changing filename (to make many PNG images in series - * with a different name, for example), and to allow you to use string type objects which can be easily - * turned into const char * (if theString is an object of type string, then it can be used as a const char * - * by saying theString.c_str()). - * It is also important to remember that whenever a function has a colour coeffiecient as its argument, - * that argument can be either an int from 0 to 65535 or a double from 0.0 to 1.0. - * It is important to make sure that you are calling the function with the type that you want. - * Remember that 1 is an int, while 1.0 is a double, and will thus determine what version of the function - * will be used. Similarly, do not make the mistake of calling for example plot(x, y, 0.0, 0.0, 65535), - * because - * there is no plot(int, int, double, double, int). - * Also, please note that plot() and read() (and the functions that use them internally) - * are protected against entering, for example, a colour coefficient that is over 65535 - * or over 1.0. Similarly, they are protected against negative coefficients. read() will return 0 - * when called outside the image range. This is actually useful as zero-padding should you need it. - * */ - - /* Compilation - * A typical compilation would look like this: - * - * g++ my_program.cc -o my_program freetype-config --cflags \ - * -I/usr/local/include -L/usr/local/lib -lpng -lpngwriter -lz -lfreetype - * - * If you did not compile PNGwriter with FreeType support, then remove the - * FreeType-related flags and add -DNO_FREETYPE above. - * */ - - /* Constructor - * The constructor requires the width and the height of the image, the background colour for the - * image and the filename of the file (a pointer or simple "myfile.png"). The background colour - * can only be initialized to a shade of grey (once the object has been created you can do whatever - * you want, though), because generally one wants either a white (65535 or 1.0) or a black (0 or 0.0) - * background to start with. - * The default constructor creates a PNGwriter instance that is 250x250, white background, - * and filename "out.png". - * Tip: The filename can be given as easily as: - * pngwriter mypng(300, 300, 0.0, "myfile.png"); - * Tip: If you are going to create a PNGwriter instance for reading in a file that already exists, - * then width and height can be 1 pixel, and the size will be automatically adjusted once you use - * readfromfile(). - * */ - pngwriter(); - pngwriter(const pngwriter &rhs); - pngwriter(int width, int height, int backgroundcolour, char * filename); - pngwriter(int width, int height, double backgroundcolour, char * filename); - pngwriter(int width, int height, int backgroundcolour, const char * filename); - pngwriter(int width, int height, double backgroundcolour, const char * filename); - - /* Destructor - * */ - ~pngwriter(); - - /* Assignment Operator - * */ - pngwriter & operator = (const pngwriter & rhs); - - /* Plot - * With this function a pixel at coordinates (x, y) can be set to the desired colour. - * The pixels are numbered starting from (1, 1) and go to (width, height). - * As with most functions in PNGwriter, it has been overloaded to accept either int arguments - * for the colour coefficients, or those of type double. If they are of type int, - * they go from 0 to 65535. If they are of type double, they go from 0.0 to 1.0. - * Tip: To plot using red, then specify plot(x, y, 1.0, 0.0, 0.0). To make pink, - * just add a constant value to all three coefficients, like this: - * plot(x, y, 1.0, 0.4, 0.4). - * Tip: If nothing is being plotted to your PNG file, make sure that you remember - * to close() the instance before your program is finished, and that the x and y position - * is actually within the bounds of your image. If either is not, then PNGwriter will - * not complain-- it is up to you to check for this! - * Tip: If you try to plot with a colour coefficient out of range, a maximum or minimum - * coefficient will be assumed, according to the given coefficient. For example, attempting - * to plot plot(x, y, 1.0,-0.2,3.7) will set the green coefficient to 0 and the red coefficient - * to 1.0. - * */ - void plot(int x, int y, int red, int green, int blue); - void plot(int x, int y, double red, double green, double blue); - - /* Plot HSV - * With this function a pixel at coordinates (x, y) can be set to the desired colour, - * but with the colour coefficients given in the Hue, Saturation, Value colourspace. - * This has the advantage that one can determine the colour that will be plotted with - * only one parameter, the Hue. The colour coefficients must go from 0 to 65535 and - * be of type int, or be of type double and go from 0.0 to 1.0. - * */ - void plotHSV(int x, int y, double hue, double saturation, double value); - void plotHSV(int x, int y, int hue, int saturation, int value); - - /* Read - * With this function we find out what colour the pixel (x, y) is. If "colour" is 1, - * it will return the red coefficient, if it is set to 2, the green one, and if - * it set to 3, the blue colour coefficient will be returned, - * and this returned value will be of type int and be between 0 and 65535. - * Note that if you call read() on a pixel outside the image range, the value returned - * will be 0. - * */ - int read(int x, int y, int colour) const; - - /* Read, Average - * Same as the above, only that the average of the three colour coefficients is returned. - */ - int read(int x, int y) const; - - /* dRead - * With this function we find out what colour the pixel (x, y) is. If "colour" is 1, - * it will return the red coefficient, if it is set to 2, the green one, and if - * it set to 3, the blue colour coefficient will be returned, - * and this returned value will be of type double and be between 0.0 and 1.0. - * Note that if you call dread() outside the image range, the value returned will be 0.0 - * */ - double dread(int x, int y, int colour) const; - - /* dRead, Average - * Same as the above, only that the average of the three colour coefficients is returned. - */ - double dread(int x, int y) const; - - /* Read HSV - * With this function we find out what colour the pixel (x, y) is, but in the Hue, - * Saturation, Value colourspace. If "colour" is 1, - * it will return the Hue coefficient, if it is set to 2, the Saturation one, and if - * it set to 3, the Value colour coefficient will be returned, and this returned - * value will be of type int and be between 0 and 65535. Important: If you attempt - * to read the Hue of a pixel that is a shade of grey, the value returned will be - * nonsensical or even NaN. This is just the way the RGB -> HSV algorithm works: - * the Hue of grey is not defined. You might want to check whether the pixel - * you are reading is grey before attempting a readHSV(). - * Tip: This is especially useful for categorizing sections of the image according - * to their colour. - * */ - int readHSV(int x, int y, int colour) const; - - /* dRead HSV - * With this function we find out what colour the pixel (x, y) is, but in the Hue, - * Saturation, Value colourspace. If "colour" is 1, - * it will return the Hue coefficient, if it is set to 2, the Saturation one, and if - * it set to 3, the Value colour coefficient will be returned, - * and this returned value will be of type double and be between 0.0 and 1.0. - * */ - double dreadHSV(int x, int y, int colour) const; - - /* Clear - * The whole image is set to black. - * */ - void clear(void); - - /* Close - * Close the instance of the class, and write the image to disk. - * Tip: If you do not call this function before your program ends, no image - * will be written to disk. - * */ - void close(void); - - /* Rename - * To rename the file once an instance of pngwriter has been created. - * Useful for assigning names to files based upon their content. - * Tip: This is as easy as calling pngwriter_rename("newname.png") - * If the argument is a long unsigned int, for example 77, the filename will be changed to - * 0000000077.png - * Tip: Use this to create sequences of images for movie generation. - * */ - void pngwriter_rename(char * newname); - void pngwriter_rename(const char * newname); - void pngwriter_rename(long unsigned int index); - - /* Figures - * These functions draw basic shapes. Available in both int and double versions. - * The line functions use the fast Bresenham algorithm. Despite the name, - * the square functions draw rectangles. The circle functions use a fast - * integer math algorithm. The filled circle functions make use of sqrt(). - * */ - void line(int xfrom, int yfrom, int xto, int yto, int red, int green,int blue); - void line(int xfrom, int yfrom, int xto, int yto, double red, double green,double blue); - - void triangle(int x1, int y1, int x2, int y2, int x3, int y3, int red, int green, int blue); - void triangle(int x1, int y1, int x2, int y2, int x3, int y3, double red, double green, double blue); - - void square(int xfrom, int yfrom, int xto, int yto, int red, int green,int blue); - void square(int xfrom, int yfrom, int xto, int yto, double red, double green,double blue); - - void filledsquare(int xfrom, int yfrom, int xto, int yto, int red, int green,int blue); - void filledsquare(int xfrom, int yfrom, int xto, int yto, double red, double green,double blue); - - void circle(int xcentre, int ycentre, int radius, int red, int green, int blue); - void circle(int xcentre, int ycentre, int radius, double red, double green, double blue); - - void filledcircle(int xcentre, int ycentre, int radius, int red, int green, int blue); - void filledcircle(int xcentre, int ycentre, int radius, double red, double green, double blue); - - - /* Read From File - * Open the existing PNG image, and copy it into this instance of the class. It is important to mention - * that PNG variants are supported. Very generally speaking, most PNG files can now be read (as of version 0.5.4), - * but if they have an alpha channel it will be completely stripped. If the PNG file uses GIF-style transparency - * (where one colour is chosen to be transparent), PNGwriter will not read the image properly, but will not - * complain. Also, if any ancillary chunks are included in the PNG file (chroma, filter, etc.), it will render - * with a slightly different tonality. For the vast majority of PNGs, this should not be an issue. Note: - * If you read an 8-bit PNG, the internal representation of that instance of PNGwriter will be 8-bit (PNG - * files of less than 8 bits will be upscaled to 8 bits). To convert it to 16-bit, just loop over all pixels, - * reading them into a new instance of PNGwriter. New instances of PNGwriter are 16-bit by default. - * */ - - void readfromfile(char * name); - void readfromfile(const char * name); - - /* Get Height - * When you open a PNG with readfromfile() you can find out its height with this function. - * */ - int getheight(void) const; - - /* Get Width - * When you open a PNG with readfromfile() you can find out its width with this function. - * */ - int getwidth(void) const; - - /* Set Compression Level - * Set the compression level that will be used for the image. -1 is to use the default, - * 0 is none, 9 is best compression. - * Remember that this will affect how long it will take to close() the image. A value of 2 or 3 - * is good enough for regular use, but for storage or transmission you might want to take the time - * to set it at 9. - * */ - void setcompressionlevel(int level); - - /* Get Bit Depth - * When you open a PNG with readfromfile() you can find out its bit depth with this function. - * Mostly for troubleshooting uses. - * */ - int getbitdepth(void) const; - - /* Get Colour Type - * When you open a PNG with readfromfile() you can find out its colour type (libpng categorizes - * different styles of image data with this number). - * Mostly for troubleshooting uses. - * */ - int getcolortype(void) const; - - /* Set Gamma Coeff - * Set the image's gamma (file gamma) coefficient. This is experimental, but use it if your image's colours seem too bright - * or too dark. The default value of 0.5 should be fine. The standard disclaimer about Mac and PC gamma - * settings applies. - * */ - void setgamma(double gamma); - - - /* Get Gamma Coeff - * Get the image's gamma coefficient. This is experimental. - * */ - double getgamma(void) const; - - /* Bezier Curve - * (After Frenchman Pierre Bezier from Regie Renault) - * A collection of formulae for describing curved lines - * and surfaces, first used in 1972 to model automobile surfaces. - * (from the The Free On-line Dictionary of Computing) - * See http://www.moshplant.com/direct-or/bezier/ for one of many - * available descriptions of bezier curves. - * There are four points used to define the curve: the two endpoints - * of the curve are called the anchor points, while the other points, - * which define the actual curvature, are called handles or control points. - * Moving the handles lets you modify the shape of the curve. - * */ - - void bezier( int startPtX, int startPtY, - int startControlX, int startControlY, - int endPtX, int endPtY, - int endControlX, int endControlY, - double red, double green, double blue); - - void bezier( int startPtX, int startPtY, - int startControlX, int startControlY, - int endPtX, int endPtY, - int endControlX, int endControlY, - int red, int green, int blue); - - /* Set Text - * Sets the text information in the PNG header. If it is not called, the default is used. - */ - void settext(char * title, char * author, char * description, char * software); - void settext(const char * title, const char * author, const char * description, const char * software); - - - /* Version Number - * Returns the PNGwriter version number. - */ - static double version(void); - - /* Write PNG - * Writes the PNG image to disk. You can still change the PNGwriter instance after this. - * Tip: This is exactly the same as close(), but easier to remember. - * Tip: To make a sequence of images using only one instance of PNGwriter, alter the image, change its name, - * write_png(), then alter the image, change its name, write_png(), etc. - */ - void write_png(void); - - /* Plot Text - * Uses the Freetype2 library to set text in the image. face_path is the file path to a - * TrueType font file (.ttf) (FreeType2 can also handle other types). fontsize specifices the approximate - * height of the rendered font in pixels. x_start and y_start specify the placement of the - * lower, left corner of the text string. angle is the text angle in radians. text is the text to be rendered. - * The colour coordinates can be doubles from 0.0 to 1.0 or ints from 0 to 65535. - * Tip: PNGwriter installs a few fonts in /usr/local/share/pngwriter/fonts to get you started. - * Tip: Remember to add -DNO_FREETYPE to your compilation flags if PNGwriter was compiled without FreeType support. - * */ - void plot_text(char * face_path, int fontsize, int x_start, int y_start, double angle, char * text, double red, double green, double blue); - void plot_text(char * face_path, int fontsize, int x_start, int y_start, double angle, char * text, int red, int green, int blue); - - - /* Plot UTF-8 Text - * Same as the above, but the text to be plotted is encoded in UTF-8. Why would you want this? To be able to plot - * all characters available in a large TrueType font, for example: for rendering Japenese, Chinese and other - * languages not restricted to the standard 128 character ASCII space. - * Tip: The quickest way to get a string into UTF-8 is to write it in an adequate text editor, and save it as a file - * in UTF-8 encoding, which can then be read in in binary mode. - * */ - void plot_text_utf8(char * face_path, int fontsize, int x_start, int y_start, double angle, char * text, double red, double green, double blue); - void plot_text_utf8(char * face_path, int fontsize, int x_start, int y_start, double angle, char * text, int red, int green, int blue); - - - /* Bilinear Interpolation of Image - * Given a floating point coordinate (x from 0.0 to width, y from 0.0 to height), - * this function will return the interpolated colour intensity specified by - * colour (where red = 1, green = 2, blue = 3). - * bilinear_interpolate_read() returns an int from 0 to 65535, and - * bilinear_interpolate_dread() returns a double from 0.0 to 1.0. - * Tip: Especially useful for enlarging an image. - * */ - int bilinear_interpolation_read(double x, double y, int colour) const; - double bilinear_interpolation_dread(double x, double y, int colour) const; - - /* Plot Blend - * Plots the colour given by red, green blue, but blended with the existing pixel - * value at that position. opacity is a double that goes from 0.0 to 1.0. - * 0.0 will not change the pixel at all, and 1.0 will plot the given colour. - * Anything in between will be a blend of both pixel levels. Please note: This is neither - * alpha channel nor PNG transparency chunk support. This merely blends the plotted pixels. - * */ - - void plot_blend(int x, int y, double opacity, int red, int green, int blue); - void plot_blend(int x, int y, double opacity, double red, double green, double blue); - - - /* Invert - * Inverts the image in RGB colourspace. - * */ - void invert(void); - - /* Resize Image - * Resizes the PNGwriter instance. Note: All image data is set to black (this is - * a resizing, not a scaling, of the image). - * */ - void resize(int width, int height); - - /* Boundary Fill - * All pixels adjacent to the start pixel will be filled with the fill colour, until the boundary colour is encountered. - * For example, calling boundary_fill() with the boundary colour set to red, on a pixel somewhere inside a red circle, - * will fill the entire circle with the desired fill colour. If, on the other hand, the circle is not the boundary colour, - * the rest of the image will be filled. - * The colour components are either doubles from 0.0 to 1.0 or ints from 0 to 65535. - * */ - void boundary_fill(int xstart, int ystart, double boundary_red,double boundary_green,double boundary_blue,double fill_red, double fill_green, double fill_blue) ; - void boundary_fill(int xstart, int ystart, int boundary_red,int boundary_green,int boundary_blue,int fill_red, int fill_green, int fill_blue) ; - - /* Flood Fill - * All pixels adjacent to the start pixel will be filled with the fill colour, if they are the same colour as the - * start pixel. For example, calling flood_fill() somewhere in the interior of a solid blue rectangle will colour - * the entire rectangle the fill colour. The colour components are either doubles from 0.0 to 1.0 or ints from 0 to 65535. - * */ - void flood_fill(int xstart, int ystart, double fill_red, double fill_green, double fill_blue) ; - void flood_fill(int xstart, int ystart, int fill_red, int fill_green, int fill_blue) ; - - /* Polygon - * This function takes an array of integer values containing the coordinates of the vertexes of a polygon. - * Note that if you want a closed polygon, you must repeat the first point's coordinates for the last point. - * It also requires the number of points contained in the array. For example, if you wish to plot a triangle, - * the array will contain 6 elements, and the number of points is 3. Be very careful about this; if you specify the wrong number - * of points, your program will either segfault or produce points at nonsensical coordinates. - * The colour components are either doubles from 0.0 to 1.0 or ints from 0 to 65535. - * */ - void polygon(int * points, int number_of_points, double red, double green, double blue); - void polygon(int * points, int number_of_points, int red, int green, int blue); - - /* Plot CMYK - * Plot a point in the Cyan, Magenta, Yellow, Black colourspace. Please note that this colourspace is - * lossy, i.e. it cannot reproduce all colours on screen that RGB can. The difference, however, is - * barely noticeable. The algorithm used is a standard one. The colour components are either - * doubles from 0.0 to 1.0 or ints from 0 to 65535. - * */ - void plotCMYK(int x, int y, double cyan, double magenta, double yellow, double black); - void plotCMYK(int x, int y, int cyan, int magenta, int yellow, int black); - - /* Read CMYK, Double version - * Get a pixel in the Cyan, Magenta, Yellow, Black colourspace. if 'colour' is 1, the Cyan component will be returned - * as a double from 0.0 to 1.0. If 'colour is 2, the Magenta colour component will be returned, and so on, up to 4. - * */ - double dreadCMYK(int x, int y, int colour) const; - - /* Read CMYK - * Same as the above, but the colour components returned are an int from 0 to 65535. - * */ - int readCMYK(int x, int y, int colour) const; - - /* Scale Proportional - * Scale the image using bilinear interpolation. If k is greater than 1.0, the image will be enlarged. - * If k is less than 1.0, the image will be shrunk. Negative or null values of k are not allowed. - * The image will be resized and the previous content will be replaced by the scaled image. - * Tip: use getheight() and getwidth() to find out the new width and height of the scaled image. - * Note: After scaling, all images will have a bit depth of 16, even if the original image had - * a bit depth of 8. - * */ - void scale_k(double k); - - /* Scale Non-Proportional - * Scale the image using bilinear interpolation, with different horizontal and vertical scale factors. - * */ - void scale_kxky(double kx, double ky); - - /* Scale To Target Width and Height - * Scale the image in such a way as to meet the target width and height. - * Tip: if you want to keep the image proportional, scale_k() might be more appropriate. - * */ - void scale_wh(int finalwidth, int finalheight); - - - /* Blended Functions - * All these functions are identical to their non-blended types. They take an extra argument, opacity, which is - * a double from 0.0 to 1.0 and represents how much of the original pixel value is retained when plotting the - * new pixel. In other words, if opacity is 0.7, then after plotting, the new pixel will be 30% of the - * original colour the pixel was, and 70% of the new colour, whatever that may be. As usual, each function - * is available in int or double versions. Please note: This is neither alpha channel nor PNG transparency chunk support. This merely blends the plotted pixels. - * */ - - // Start Blended Functions - - void plotHSV_blend(int x, int y, double opacity, double hue, double saturation, double value); - void plotHSV_blend(int x, int y, double opacity, int hue, int saturation, int value); - - void line_blend(int xfrom, int yfrom, int xto, int yto, double opacity, int red, int green,int blue); - void line_blend(int xfrom, int yfrom, int xto, int yto, double opacity, double red, double green,double blue); - - void square_blend(int xfrom, int yfrom, int xto, int yto, double opacity, int red, int green,int blue); - void square_blend(int xfrom, int yfrom, int xto, int yto, double opacity, double red, double green,double blue); - - void filledsquare_blend(int xfrom, int yfrom, int xto, int yto, double opacity, int red, int green,int blue); - void filledsquare_blend(int xfrom, int yfrom, int xto, int yto, double opacity, double red, double green,double blue); - - void circle_blend(int xcentre, int ycentre, int radius, double opacity, int red, int green, int blue); - void circle_blend(int xcentre, int ycentre, int radius, double opacity, double red, double green, double blue); - - void filledcircle_blend(int xcentre, int ycentre, int radius, double opacity, int red, int green, int blue); - void filledcircle_blend(int xcentre, int ycentre, int radius, double opacity, double red, double green, double blue); - - void bezier_blend( int startPtX, int startPtY, - int startControlX, int startControlY, - int endPtX, int endPtY, - int endControlX, int endControlY, - double opacity, - double red, double green, double blue); - - void bezier_blend( int startPtX, int startPtY, - int startControlX, int startControlY, - int endPtX, int endPtY, - int endControlX, int endControlY, - double opacity, - int red, int green, int blue); - - void plot_text_blend(char * face_path, int fontsize, int x_start, int y_start, double angle, char * text, double opacity, double red, double green, double blue); - void plot_text_blend(char * face_path, int fontsize, int x_start, int y_start, double angle, char * text, double opacity, int red, int green, int blue); - - void plot_text_utf8_blend(char * face_path, int fontsize, int x_start, int y_start, double angle, char * text, double opacity, double red, double green, double blue); - void plot_text_utf8_blend(char * face_path, int fontsize, int x_start, int y_start, double angle, char * text, double opacity, int red, int green, int blue); - - void boundary_fill_blend(int xstart, int ystart, double opacity, double boundary_red,double boundary_green,double boundary_blue,double fill_red, double fill_green, double fill_blue) ; - void boundary_fill_blend(int xstart, int ystart, double opacity, int boundary_red,int boundary_green,int boundary_blue,int fill_red, int fill_green, int fill_blue) ; - - void flood_fill_blend(int xstart, int ystart, double opacity, double fill_red, double fill_green, double fill_blue) ; - void flood_fill_blend(int xstart, int ystart, double opacity, int fill_red, int fill_green, int fill_blue) ; - - void polygon_blend(int * points, int number_of_points, double opacity, double red, double green, double blue); - void polygon_blend(int * points, int number_of_points, double opacity, int red, int green, int blue); - - void plotCMYK_blend(int x, int y, double opacity, double cyan, double magenta, double yellow, double black); - void plotCMYK_blend(int x, int y, double opacity, int cyan, int magenta, int yellow, int black); - - // End of Blended Functions - - /* Laplacian - * This function applies a discrete laplacian to the image, multiplied by a constant factor. - * The kernel used in this case is: - * 1.0 1.0 1.0 - * 1.0 -8.0 1.0 - * 1.0 1.0 1.0 - * Basically, this works as an edge detector. The current pixel is assigned the sum of all neighbouring - * pixels, multiplied by the corresponding kernel element. For example, imagine a pixel and its 8 neighbours: - * 1.0 1.0 0.0 0.0 - * 1.0 ->1.0<- 0.0 0.0 - * 1.0 1.0 0.0 0.0 - * This represents a border between white and black, black is on the right. Applying the laplacian to - * the pixel specified above pixel gives: - * 1.0*1.0 + 1.0*1.0 + 0.0*1.0 + - * 1.0*1.0 + 1.0*-8.0 + 0.0*1.0 + - * 1.0*1.0 + 1.0*1.0 + 0.0*1.0 = -3.0 - * Applying this to the pixel to the right of the pixel considered previously, we get a sum of 3.0. - * That is, after passing over an edge, we get a high value for the pixel adjacent to the edge. Since - * PNGwriter limits the colour components if they are off-scale, and the result of the laplacian - * may be negative, a scale factor and an offset value are included. This might be useful for - * keeping things within range or for bringing out more detail in the edge detection. The - * final pixel value will be given by: - * final value = laplacian(original pixel)*k + offset - * Tip: Try a value of 1.0 for k to start with, and then experiment with other values. - * */ - void laplacian(double k, double offset); - - /* Filled Triangle - * Draws the triangle specified by the three pairs of points in the colour specified - * by the colour coefficients. The colour components are either doubles from 0.0 to - * 1.0 or ints from 0 to 65535. - * */ - void filledtriangle(int x1,int y1,int x2,int y2,int x3,int y3, int red, int green, int blue); - void filledtriangle(int x1,int y1,int x2,int y2,int x3,int y3, double red, double green, double blue); - - /* Filled Triangle, Blended - * Draws the triangle specified by the three pairs of points in the colour specified - * by the colour coefficients, and blended with the background. See the description for Blended Functions. - * The colour components are either doubles from 0.0 to 1.0 or ints from 0 to 65535. - * */ - void filledtriangle_blend(int x1,int y1,int x2,int y2,int x3,int y3, double opacity, int red, int green, int blue); - void filledtriangle_blend(int x1,int y1,int x2,int y2,int x3,int y3, double opacity, double red, double green, double blue); - - /* Arrow, Filled Arrow - * Plots an arrow from (x1, y1) to (x2, y2) with the arrowhead at the second point, given the size in pixels - * and the angle in radians of the arrowhead. The plotted arrow consists of one main line, and two smaller - * lines originating from the second point. Filled Arrow plots the same, but the arrowhead is a solid triangle. - * Tip: An angle of 10 to 30 degrees looks OK. - * */ - - void arrow( int x1,int y1,int x2,int y2,int size, double head_angle, double red, double green, double blue); - void arrow( int x1,int y1,int x2,int y2,int size, double head_angle, int red, int green, int blue); - - void filledarrow( int x1,int y1,int x2,int y2,int size, double head_angle, double red, double green, double blue); - void filledarrow( int x1,int y1,int x2,int y2,int size, double head_angle, int red, int green, int blue); - - /* Cross, Maltese Cross - * Plots a simple cross at x, y, with the specified height and width, and in the specified colour. - * Maltese cross plots a cross, as before, but adds bars at the end of each arm of the cross. - * The size of these bars is specified with x_bar_height and y_bar_width. - * The cross will look something like this: - * - * ----- <-- ( y_bar_width) - * | - * | - * |-------| <-- ( x_bar_height ) - * | - * | - * ----- - * */ - - void cross( int x, int y, int xwidth, int yheight, double red, double green, double blue); - void cross( int x, int y, int xwidth, int yheight, int red, int green, int blue); - - void maltesecross( int x, int y, int xwidth, int yheight, int x_bar_height, int y_bar_width, double red, double green, double blue); - void maltesecross( int x, int y, int xwidth, int yheight, int x_bar_height, int y_bar_width, int red, int green, int blue); - - /* Diamond and filled diamond - * Plots a diamond shape, given the x, y position, the width and height, and the colour. - * Filled diamond plots a filled diamond. - * */ - - void filleddiamond( int x, int y, int width, int height, int red, int green, int blue); - void diamond(int x, int y, int width, int height, int red, int green, int blue); - - void filleddiamond( int x, int y, int width, int height, double red, double green, double blue); - void diamond(int x, int y, int width, int height, double red, double green, double blue); - - /* Get Text Width, Get Text Width UTF8 - * Returns the approximate width, in pixels, of the specified *unrotated* text. It is calculated by adding - * each letter's width and kerning value (as specified in the TTF file). Note that this will not - * give the position of the farthest pixel, but it will give a pretty good idea of what area the - * text will occupy. Tip: The text, when plotted unrotated, will fit approximately in a box with its lower left corner at - * (x_start, y_start) and upper right at (x_start + width, y_start + size), where width is given by get_text_width() - * and size is the specified size of the text to be plotted. Tip: Text plotted at position - * (x_start, y_start), rotated with a given 'angle', and of a given 'size' - * whose width is 'width', will fit approximately inside a rectangle whose corners are at - * 1 (x_start, y_start) - * 2 (x_start + width*cos(angle), y_start + width*sin(angle)) - * 3 (x_start + width*cos(angle) - size*sin(angle), y_start + width*sin(angle) + size*cos(angle)) - * 4 (x_start - size*sin(angle), y_start + size*cos(angle)) - * */ - - int static get_text_width(char * face_path, int fontsize, char * text); - - int static get_text_width_utf8(char * face_path, int fontsize, char * text); - - -}; - - -#endif diff --git a/src/Heat_Equation_ParallelPrograming_Comparison/MPI_OpenMP/CMakeLists.txt b/src/Heat_Equation_ParallelPrograming_Comparison/MPI_OpenMP/CMakeLists.txt index 9baa77b..8891ba8 100644 --- a/src/Heat_Equation_ParallelPrograming_Comparison/MPI_OpenMP/CMakeLists.txt +++ b/src/Heat_Equation_ParallelPrograming_Comparison/MPI_OpenMP/CMakeLists.txt @@ -1,14 +1,12 @@ +project(HEATDemoHybrid) -#project(MPI_bcast) - -######## A simple cmakelists.txt file for ... ############# - +######## A simple cmakelists.txt file for Open... ############# +#cmake_minimum_required(VERSION 3.26) cmake_minimum_required(VERSION 3.17) #set(CMAKE_CXX_STANDARD 14) #set(CMAKE_BUILD_TYPE Debug) set(CMAKE_BUILD_TYPE Release) #set(CMAKE_CXX_COMPILER "/usr/local/bin/g++") - #set(CMAKE_CXX_STANDARD 14) #set(CMAKE_CXX_COMPILER "/usr/local/bin/g++") #set(CMAKE_C_COMPILER "/usr/bin/clang-14") @@ -16,18 +14,12 @@ set(CMAKE_BUILD_TYPE Release) #set(CMAKE_CXX_COMPILER "/usr/bin/gcc") #set(CMAKE_CXX_COMPILER "/usr/bin/g++-11") -if(TRUE) - find_package(PNGwriter) - if(PNGwriter_FOUND) - MESSAGE("{PNGwrite_LIBRARIES}") - else (PNGwriter_FOUND) - MESSAGE(SEND_ERROR "{PNGwrite_LIBRARIES Not Found}") - endif(PNGwriter_FOUND) -endif() +include_directories("../common") -if(FALSE) + +if(TRUE) find_package(MPI REQUIRED) if (MPI_FOUND) MESSAGE("{MPI_CXX_LIBRARIES}") @@ -36,32 +28,46 @@ if(FALSE) endif(MPI_FOUND) endif() -if(FALSE) +if(TRUE) find_package(OpenMP) if (OpenMP_CXX_FOUND) MESSAGE("{OpenMP_CXX_LIBRARIES}") else (OpenMP_CXX_FOUND) - MESSAGE (SEND_ERROR "This application cannot compile without OpenMPI") + MESSAGE (SEND_ERROR "This application cannot compile without OpenMP") endif(OpenMP_CXX_FOUND) - endif() -if(TRUE) - find_package(OpenMP REQUIRED) -endif() +find_package(PNG REQUIRED) +if (PNG_FOUND) + MESSAGE("{PNG_LIBRARIES}") + else (PNG_FOUND) + MESSAGE (SEND_ERROR "This application cannot compile without PNG") + endif(PNG_FOUND) + + +#file(GLOB my_cpp_list "${CMAKE_CURRENT_SOURCE_DIR}/common/*.c") +file(GLOB my_common_list + "${CMAKE_CURRENT_SOURCE_DIR}/../common/*.c" + "${CMAKE_CURRENT_SOURCE_DIR}/../common/*.h" +) +message(${CMAKE_CURRENT_SOURCE_DIR}) +foreach(file_path ${my_cpp_list} ${my_common_list}) + message(${file_path}) +endforeach() -file(GLOB SOURCES - "*.h" - "*.cpp" +file(GLOB All_SRC + "*.h" + "*.cpp" + "*.c" ) -add_executable(HeatOpenMP ${SOURCES}) -include_directories(SYSTEM ${MPI_INCLUDES_PATH}) -target_include_directories(HeatOpenMP PUBLIC ${MPI_CXX_INCLUDE_DIRS} PUBLIC OpenMP::OpenMP_CXX) -target_link_libraries(HeatOpenMP PUBLIC ${MPI_CXX_LIBRARIES} PUBLIC OpenMP::OpenMP_CXX PRIVATE PNGwriter::PNGwriter ) +add_executable(HEATDemoHybid main.cpp ${All_SRC} ${my_common_list}) -########### end #################################### + +include_directories(SYSTEM ${MPI_INCLUDES_PATH}) +target_include_directories(HEATDemoHybid PUBLIC ${MPI_CXX_INCLUDE_DIRS} PUBLIC OpenMP::OpenMP_CXX ${PNG_INCLUDE_DIR}) +target_link_libraries(HEATDemoHybid PUBLIC ${MPI_CXX_LIBRARIES} PUBLIC OpenMP::OpenMP_CXX ${PNG_LIBRARY}) diff --git a/src/Heat_Equation_ParallelPrograming_Comparison/MPI_OpenMP/MakefileOld b/src/Heat_Equation_ParallelPrograming_Comparison/MPI_OpenMP/OldMakefile similarity index 100% rename from src/Heat_Equation_ParallelPrograming_Comparison/MPI_OpenMP/MakefileOld rename to src/Heat_Equation_ParallelPrograming_Comparison/MPI_OpenMP/OldMakefile diff --git a/src/Heat_Equation_ParallelPrograming_Comparison/common/pngwriter.c b/src/Heat_Equation_ParallelPrograming_Comparison/common/pngwriter.c new file mode 100644 index 0000000..ce2dbe1 --- /dev/null +++ b/src/Heat_Equation_ParallelPrograming_Comparison/common/pngwriter.c @@ -0,0 +1,221 @@ +#include +#include +#include +#include +#include "pngwriter.h" + +/* Datatype for RGB pixel */ +typedef struct { + uint8_t red; + uint8_t green; + uint8_t blue; +} pixel_t; + + +void cmap(double value, const double scaling, const double maxval, + pixel_t *pix); + +static int heat_colormap[256][3] = { + {59, 76, 192}, {59, 76, 192}, {60, 78, 194}, {61, 80, 195}, + {62, 81, 197}, {64, 83, 198}, {65, 85, 200}, {66, 87, 201}, + {67, 88, 203}, {68, 90, 204}, {69, 92, 206}, {71, 93, 207}, + {72, 95, 209}, {73, 97, 210}, {74, 99, 211}, {75, 100, 213}, + {77, 102, 214}, {78, 104, 215}, {79, 105, 217}, {80, 107, 218}, + {82, 109, 219}, {83, 110, 221}, {84, 112, 222}, {85, 114, 223}, + {87, 115, 224}, {88, 117, 225}, {89, 119, 227}, {90, 120, 228}, + {92, 122, 229}, {93, 124, 230}, {94, 125, 231}, {96, 127, 232}, + {97, 129, 233}, {98, 130, 234}, {100, 132, 235}, {101, 133, 236}, + {102, 135, 237}, {103, 137, 238}, {105, 138, 239}, {106, 140, 240}, + {107, 141, 240}, {109, 143, 241}, {110, 144, 242}, {111, 146, 243}, + {113, 147, 244}, {114, 149, 244}, {116, 150, 245}, {117, 152, 246}, + {118, 153, 246}, {120, 155, 247}, {121, 156, 248}, {122, 157, 248}, + {124, 159, 249}, {125, 160, 249}, {127, 162, 250}, {128, 163, 250}, + {129, 164, 251}, {131, 166, 251}, {132, 167, 252}, {133, 168, 252}, + {135, 170, 252}, {136, 171, 253}, {138, 172, 253}, {139, 174, 253}, + {140, 175, 254}, {142, 176, 254}, {143, 177, 254}, {145, 179, 254}, + {146, 180, 254}, {147, 181, 255}, {149, 182, 255}, {150, 183, 255}, + {152, 185, 255}, {153, 186, 255}, {154, 187, 255}, {156, 188, 255}, + {157, 189, 255}, {158, 190, 255}, {160, 191, 255}, {161, 192, 255}, + {163, 193, 255}, {164, 194, 254}, {165, 195, 254}, {167, 196, 254}, + {168, 197, 254}, {169, 198, 254}, {171, 199, 253}, {172, 200, 253}, + {173, 201, 253}, {175, 202, 252}, {176, 203, 252}, {177, 203, 252}, + {179, 204, 251}, {180, 205, 251}, {181, 206, 250}, {183, 207, 250}, + {184, 207, 249}, {185, 208, 249}, {186, 209, 248}, {188, 209, 247}, + {189, 210, 247}, {190, 211, 246}, {191, 211, 246}, {193, 212, 245}, + {194, 213, 244}, {195, 213, 243}, {196, 214, 243}, {198, 214, 242}, + {199, 215, 241}, {200, 215, 240}, {201, 216, 239}, {202, 216, 239}, + {204, 217, 238}, {205, 217, 237}, {206, 217, 236}, {207, 218, 235}, + {208, 218, 234}, {209, 218, 233}, {210, 219, 232}, {211, 219, 231}, + {212, 219, 230}, {214, 220, 229}, {215, 220, 228}, {216, 220, 227}, + {217, 220, 225}, {218, 220, 224}, {219, 220, 223}, {220, 221, 222}, + {221, 221, 221}, {222, 220, 219}, {223, 220, 218}, {224, 219, 216}, + {225, 219, 215}, {226, 218, 214}, {227, 218, 212}, {228, 217, 211}, + {229, 216, 209}, {230, 216, 208}, {231, 215, 206}, {232, 215, 205}, + {233, 214, 203}, {233, 213, 202}, {234, 212, 200}, {235, 212, 199}, + {236, 211, 197}, {237, 210, 196}, {237, 209, 194}, {238, 208, 193}, + {239, 208, 191}, {239, 207, 190}, {240, 206, 188}, {240, 205, 187}, + {241, 204, 185}, {242, 203, 183}, {242, 202, 182}, {243, 201, 180}, + {243, 200, 179}, {243, 199, 177}, {244, 198, 176}, {244, 197, 174}, + {245, 196, 173}, {245, 195, 171}, {245, 194, 169}, {246, 193, 168}, + {246, 192, 166}, {246, 190, 165}, {246, 189, 163}, {247, 188, 161}, + {247, 187, 160}, {247, 186, 158}, {247, 184, 157}, {247, 183, 155}, + {247, 182, 153}, {247, 181, 152}, {247, 179, 150}, {247, 178, 149}, + {247, 177, 147}, {247, 175, 146}, {247, 174, 144}, {247, 172, 142}, + {247, 171, 141}, {247, 170, 139}, {247, 168, 138}, {247, 167, 136}, + {247, 165, 135}, {246, 164, 133}, {246, 162, 131}, {246, 161, 130}, + {246, 159, 128}, {245, 158, 127}, {245, 156, 125}, {245, 155, 124}, + {244, 153, 122}, {244, 151, 121}, {243, 150, 119}, {243, 148, 117}, + {242, 147, 116}, {242, 145, 114}, {241, 143, 113}, {241, 142, 111}, + {240, 140, 110}, {240, 138, 108}, {239, 136, 107}, {239, 135, 105}, + {238, 133, 104}, {237, 131, 102}, {237, 129, 101}, {236, 128, 99}, + {235, 126, 98}, {235, 124, 96}, {234, 122, 95}, {233, 120, 94}, + {232, 118, 92}, {231, 117, 91}, {230, 115, 89}, {230, 113, 88}, + {229, 111, 86}, {228, 109, 85}, {227, 107, 84}, {226, 105, 82}, + {225, 103, 81}, {224, 101, 79}, {223, 99, 78}, {222, 97, 77}, + {221, 95, 75}, {220, 93, 74}, {219, 91, 73}, {218, 89, 71}, + {217, 87, 70}, {215, 85, 69}, {214, 82, 67}, {213, 80, 66}, + {212, 78, 65}, {211, 76, 64}, {210, 74, 62}, {208, 71, 61}, + {207, 69, 60}, {206, 67, 59}, {204, 64, 57}, {203, 62, 56}, + {202, 59, 55}, {200, 57, 54}, {199, 54, 53}, {198, 52, 51}, + {196, 49, 50}, {195, 46, 49}, {193, 43, 48}, {192, 40, 47}, + {191, 37, 46}, {189, 34, 44}, {188, 30, 43}, {186, 26, 42}, + {185, 22, 41}, {183, 17, 40}, {182, 11, 39}, {180, 4, 38} +}; + + +/* + * Save the two dimensional array as a png image + * Arguments: + * double *data - pointer to an array of nx * ny values + * int nx - number of COLUMNS to be written + * int ny - number of ROWS to be written + * char *fname - name of the picture + * char lang - either 'c' or 'f' denoting the memory + * layout. That is, if 'f' is given, then rows + * and columns are swapped. + */ +int save_png(double *data, const int height, const int width, + const char *fname, const char lang) +{ + FILE *fp; + png_structp pngstruct_ptr = NULL; + png_infop pnginfo_ptr = NULL; + png_byte **row_pointers = NULL; + int i, j; + + /* Default return status is failure */ + int status = -1; + + int pixel_size = 3; + int depth = 8; + + /* Open the file and initialize the png library. + * Note that in error cases we jump to clean up + * parts in the end of this function using goto. */ + fp = fopen(fname, "wb"); + if (fp == NULL) { + goto fopen_failed; + } + + pngstruct_ptr = + png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + + if (pngstruct_ptr == NULL) { + goto pngstruct_create_failed; + } + + pnginfo_ptr = png_create_info_struct(pngstruct_ptr); + + if (pnginfo_ptr == NULL) { + goto pnginfo_create_failed; + } + + if (setjmp(png_jmpbuf(pngstruct_ptr))) { + goto setjmp_failed; + } + + png_set_IHDR(pngstruct_ptr, pnginfo_ptr, (size_t) width, + (size_t) height, depth, PNG_COLOR_TYPE_RGB, + PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + + row_pointers = png_malloc(pngstruct_ptr, height * sizeof(png_byte *)); + + for (i = 0; i < height; i++) { + png_byte *row = png_malloc(pngstruct_ptr, + sizeof(uint8_t) * width * pixel_size); + row_pointers[i] = row; + + /* Branch according to the memory layout */ + if (lang == 'c' || lang == 'C') { + for (j = 0; j < width; j++) { + pixel_t pixel; + /* Scale the values so that values between 0 and + * 100 degrees are mapped to values between 0 and 255 */ + cmap(data[j + i * width], 2.55, 0.0, &pixel); + *row++ = pixel.red; + *row++ = pixel.green; + *row++ = pixel.blue; + } + } else if (lang == 'f' || lang == 'F') { + for (j = 0; j < width; j++) { + pixel_t pixel; + cmap(data[i + j * height], 2.55, 0.0, &pixel); + *row++ = pixel.red; + *row++ = pixel.green; + *row++ = pixel.blue; + } + } else { + fprintf(stderr, "Unknown memory order %c for pngwriter!\n", lang); + exit(EXIT_FAILURE); + } + } + + png_init_io(pngstruct_ptr, fp); + png_set_rows(pngstruct_ptr, pnginfo_ptr, row_pointers); + png_write_png(pngstruct_ptr, pnginfo_ptr, + PNG_TRANSFORM_IDENTITY, NULL); + + status = 0; + + for (i = 0; i < height; i++) { + png_free(pngstruct_ptr, row_pointers[i]); + } + png_free(pngstruct_ptr, row_pointers); + + /* Cleanup with labels */ +setjmp_failed: +pnginfo_create_failed: + png_destroy_write_struct(&pngstruct_ptr, &pnginfo_ptr); +pngstruct_create_failed: + fclose(fp); +fopen_failed: + return status; +} + +/* + * This routine sets the RGB values for the pixel_t structure using + * the colormap data heat_colormap. If the value is outside the + * acceptable png values 0, 255 blue or red color is used instead. + */ +void cmap(double value, const double scaling, const double offset, + pixel_t *pix) +{ + int ival; + + ival = (int)(value * scaling + offset); + if (ival < 0) { /* Colder than colorscale, substitute blue */ + pix->red = 0; + pix->green = 0; + pix->blue = 255; + } else if (ival > 255) { + pix->red = 255; /* Hotter than colormap, substitute red */ + pix->green = 0; + pix->blue = 0; + } else { + pix->red = heat_colormap[ival][0]; + pix->green = heat_colormap[ival][1]; + pix->blue = heat_colormap[ival][2]; + } +} + diff --git a/src/Heat_Equation_ParallelPrograming_Comparison/common/pngwriter.h b/src/Heat_Equation_ParallelPrograming_Comparison/common/pngwriter.h new file mode 100644 index 0000000..eb049f9 --- /dev/null +++ b/src/Heat_Equation_ParallelPrograming_Comparison/common/pngwriter.h @@ -0,0 +1,14 @@ +#ifndef PNGWRITER_H_ +#define PNGWRITER_H_ + +#if __cplusplus + extern "C" { +#endif + +int save_png(double *data, const int nx, const int ny, const char *fname, + const char lang); + +#if __cplusplus + } +#endif +#endif diff --git a/src/Tools/mpi_cuda_awareness_check.cpp b/src/Tools/mpi_cuda_awareness_check.cpp new file mode 100644 index 0000000..3f9082a --- /dev/null +++ b/src/Tools/mpi_cuda_awareness_check.cpp @@ -0,0 +1,44 @@ +/* + * From https://www.open-mpi.org/faq/?category=runcuda + * Command: + * $ mpic++ cuda_aware_check.cpp + * $ mpirun a.out + * Program that shows the use of CUDA-aware macro and runtime check. + * Requires Open MPI v2.0.0 or later. + */ +#include +#include "mpi.h" +#include "mpi-ext.h" +#if defined(MPIX_CUDA_AWARE_SUPPORT) +#include "mpi-ext.h" /* Needed for CUDA-aware check */ +#endif + +int main(int argc, char *argv[]) +{ + printf("Compile time check:\n"); + if (1 == MPIX_Query_cuda_support()) { + printf("This MPI library has CUDA-aware support.\n"); + } else { + printf("This MPI library does not have CUDA-aware support.\n"); + } +#if defined(MPIX_CUDA_AWARE_SUPPORT) && MPIX_CUDA_AWARE_SUPPORT + printf("This MPI library has CUDA-aware support.\n", MPIX_CUDA_AWARE_SUPPORT); +#elif defined(MPIX_CUDA_AWARE_SUPPORT) && !MPIX_CUDA_AWARE_SUPPORT + printf("This MPI library does not have CUDA-aware support.\n"); +#else + printf("This MPI library cannot determine if there is CUDA-aware support.\n"); +#endif /* MPIX_CUDA_AWARE_SUPPORT */ + + printf("Run time check:\n"); +#if defined(MPIX_CUDA_AWARE_SUPPORT) + if (1 == MPIX_Query_cuda_support()) { + printf("This MPI library has CUDA-aware support.\n"); + } else { + printf("This MPI library does not have CUDA-aware support.\n"); + } +#else /* !defined(MPIX_CUDA_AWARE_SUPPORT) */ + printf("This MPI library cannot determine if there is CUDA-aware support.\n"); +#endif /* MPIX_CUDA_AWARE_SUPPORT */ + + return 0; +}