diff --git a/CMakeLists.txt b/CMakeLists.txt index 37f1cfe80e468fa7d8c50a7f57ab7de7b01a2f51..44e40b639c2328b5512ad4c557a877d4d9cbec8f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,6 +62,12 @@ if(SYSTEM_CRAY) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -dynamic") endif() +# Cray systems +set(TARGET_KNL OFF CACHE BOOL "target Intel KNL architecture") +if(TARGET_KNL) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXXOPT_KNL}") +endif() + # targets for extermal dependencies include(ExternalProject) externalproject_add(modparser diff --git a/cmake/CompilerOptions.cmake b/cmake/CompilerOptions.cmake index 167ae04818f6c2eb791704de08d7bd99adb449fb..6dc09b961cc6a71ce69b1bf9cba5d6821e6949e8 100644 --- a/cmake/CompilerOptions.cmake +++ b/cmake/CompilerOptions.cmake @@ -13,10 +13,21 @@ if(${CMAKE_CXX_COMPILER_ID} MATCHES "Clang") set(CXXOPT_WALL "${CXXOPT_WALL} -Wno-missing-braces") endif() +if(${CMAKE_CXX_COMPILER_ID} MATCHES "GNU") + + # compiler flags for generating KNL-specific AVX512 instructions + # supported in gcc 4.9.x and later + #set(CXXOPT_KNL "-mavx512f") + set(CXXOPT_KNL "-march=knl") +endif() + if(${CMAKE_CXX_COMPILER_ID} MATCHES "Intel") # Disable warning for unused template parameter # this is raised by a templated function in the json library set(CXXOPT_WALL "${CXXOPT_WALL} -wd488") + + # compiler flags for generating KNL-specific AVX512 instructions + set(CXXOPT_KNL "-xMIC-AVX512") endif() diff --git a/data/cells_small.json b/data/cells_small.json index 01dc71bd84eb623c4a682d45e9665732d36ad57e..93c8c2f3dc3078471f337b0bb2eebc231d78364e 100644 --- a/data/cells_small.json +++ b/data/cells_small.json @@ -60,7 +60,7 @@ "indexes": [1,3,5,6,7,9,11,13,15,17,19,21,23,24,25,27,28,29,30,31,32,33,35,36,37,38,39,41,43,45,47,49,50,51,53,54,55,57,58,59,60,61,63,64,65,67,68,69,71,73], "name": "pas" }], - "parent_index": [0,0,1,0,3,0,5,6,7,0,9,2,11,10,13,10,15,12,17,14,19,14,21,16,23,24,25,16,27,28,29,30,31,32,33,20,35,36,37,38,39,20,41,26,43,26,45,42,47,42,49,50,51,48,53,54,55,48,57,58,59,60,61,62,63,64,65,62,67,68,69,70,71,70,73] + "parent_index": [0,0,1,0,3,0,5,6,7,0,9,0,11,10,13,10,15,0,17,14,19,14,21,16,23,24,25,16,27,28,29,30,31,32,33,20,35,36,37,38,39,20,41,26,43,26,45,42,47,42,49,50,51,48,53,54,55,48,57,58,59,60,61,62,63,64,65,62,67,68,69,70,71,70,73] },{ "mechanisms": [{ "indexes": [1,11,17], @@ -123,7 +123,7 @@ "indexes": [1,3,5,6,7,9,11,13,15,17,19,21,23,24,25,27,28,29,30,31,32,33,35,36,37,38,39,41,43,45,47,49,50,51,53,54,55,57,58,59,60,61,63,64,65,67,68,69,71,73], "name": "pas" }], - "parent_index": [0,0,1,0,3,0,5,6,7,0,9,2,11,10,13,10,15,12,17,14,19,14,21,16,23,24,25,16,27,28,29,30,31,32,33,20,35,36,37,38,39,20,41,26,43,26,45,42,47,42,49,50,51,48,53,54,55,48,57,58,59,60,61,62,63,64,65,62,67,68,69,70,71,70,73] + "parent_index": [0,0,1,0,3,0,5,6,7,0,9,0,11,10,13,10,15,0,17,14,19,14,21,16,23,24,25,16,27,28,29,30,31,32,33,20,35,36,37,38,39,20,41,26,43,26,45,42,47,42,49,50,51,48,53,54,55,48,57,58,59,60,61,62,63,64,65,62,67,68,69,70,71,70,73] },{ "mechanisms": [{ "indexes": [1,11,17], @@ -186,7 +186,7 @@ "indexes": [1,3,5,6,7,9,11,13,15,17,19,21,23,24,25,27,28,29,30,31,32,33,35,36,37,38,39,41,43,45,47,49,50,51,53,54,55,57,58,59,60,61,63,64,65,67,68,69,71,73], "name": "pas" }], - "parent_index": [0,0,1,0,3,0,5,6,7,0,9,2,11,10,13,10,15,12,17,14,19,14,21,16,23,24,25,16,27,28,29,30,31,32,33,20,35,36,37,38,39,20,41,26,43,26,45,42,47,42,49,50,51,48,53,54,55,48,57,58,59,60,61,62,63,64,65,62,67,68,69,70,71,70,73] + "parent_index": [0,0,1,0,3,0,5,6,7,0,9,0,11,10,13,10,15,0,17,14,19,14,21,16,23,24,25,16,27,28,29,30,31,32,33,20,35,36,37,38,39,20,41,26,43,26,45,42,47,42,49,50,51,48,53,54,55,48,57,58,59,60,61,62,63,64,65,62,67,68,69,70,71,70,73] },{ "mechanisms": [{ "indexes": [1,11,17], @@ -249,7 +249,7 @@ "indexes": [1,3,5,6,7,9,11,13,15,17,19,21,23,24,25,27,28,29,30,31,32,33,35,36,37,38,39,41,43,45,47,49,50,51,53,54,55,57,58,59,60,61,63,64,65,67,68,69,71,73], "name": "pas" }], - "parent_index": [0,0,1,0,3,0,5,6,7,0,9,2,11,10,13,10,15,12,17,14,19,14,21,16,23,24,25,16,27,28,29,30,31,32,33,20,35,36,37,38,39,20,41,26,43,26,45,42,47,42,49,50,51,48,53,54,55,48,57,58,59,60,61,62,63,64,65,62,67,68,69,70,71,70,73] + "parent_index": [0,0,1,0,3,0,5,6,7,0,9,0,11,10,13,10,15,0,17,14,19,14,21,16,23,24,25,16,27,28,29,30,31,32,33,20,35,36,37,38,39,20,41,26,43,26,45,42,47,42,49,50,51,48,53,54,55,48,57,58,59,60,61,62,63,64,65,62,67,68,69,70,71,70,73] },{ "mechanisms": [{ "indexes": [1,23,59], @@ -312,7 +312,7 @@ "indexes": [1,3,5,7,9,10,11,13,14,15,16,17,18,19,21,23,25,26,27,29,31,33,35,37,39,41,42,43,44,45,47,49,50,51,52,53,54,55,56,57,59,61,62,63,65,67,68,69,70,71,73,75,77,79,80,81,83,84,85,87,89,90,91,92,93,95,97,98,99,101,103,104,105,107,109,111,113,115,117,118,119,121,123,125,127,128,129,130,131,133,134,135,136,137,139,140,141,143,144,145,147,148,149,150,151,153,154,155,157,158,159,160,161,163,165,166,167,168,169,170,171,173,174,175,176,177,179,180,181,183,185,186,187,188,189,191,193,194,195,196,197,199,201,202,203,204,205,206,207,209,210,211,212,213,214,215,217,218,219,220,221,222,223,225,226,227,229,230,231,233,234,235,237,239,240,241,243,244,245,246,247,249,250,251,253,254,255,256,257,258,259,261,262,263,264,265,267,268,269,270,271,272,273,274,275,277,278,279,281,282,283,284,285,287,289,290,291,293,294,295,296,297,299,300,301,303,304,305,307,309,311,312,313,315,316,317,318,319,321,323,325,326,327,329,331,332,333,335,336,337,338,339,340,341,343,344,345,346,347,348,349,351,352,353,355,356,357,359,360,361,363], "name": "pas" }], - "parent_index": [0,0,1,0,3,0,5,0,7,0,9,10,11,0,13,14,15,16,17,18,19,0,21,2,23,4,25,26,27,4,29,6,31,6,33,8,35,8,37,12,39,12,41,42,43,44,45,22,47,22,49,50,51,52,53,54,55,56,57,24,59,28,61,62,63,28,65,30,67,68,69,70,71,30,73,32,75,32,77,34,79,80,81,34,83,84,85,36,87,36,89,90,91,92,93,38,95,38,97,98,99,40,101,40,103,104,105,48,107,48,109,74,111,74,113,76,115,76,117,118,119,78,121,78,123,88,125,88,127,128,129,130,131,96,133,134,135,136,137,96,139,140,141,100,143,144,145,100,147,148,149,150,151,108,153,154,155,108,157,158,159,160,161,110,163,110,165,166,167,168,169,170,171,112,173,174,175,176,177,112,179,180,181,114,183,114,185,186,187,188,189,116,191,116,193,194,195,196,197,122,199,122,201,202,203,204,205,206,207,124,209,210,211,212,213,214,215,124,217,218,219,220,221,222,223,126,225,226,227,126,229,230,231,142,233,234,235,142,237,164,239,240,241,164,243,244,245,246,247,184,249,250,251,184,253,254,255,256,257,258,259,190,261,262,263,264,265,190,267,268,269,270,271,272,273,274,275,192,277,278,279,192,281,282,283,284,285,200,287,200,289,290,291,276,293,294,295,296,297,276,299,300,301,280,303,304,305,280,307,288,309,288,311,312,313,298,315,316,317,318,319,298,321,302,323,302,325,326,327,322,329,322,331,332,333,324,335,336,337,338,339,340,341,324,343,344,345,346,347,348,349,328,351,352,353,328,355,356,357,330,359,360,361,330,363] + "parent_index": [0,0,1,0,3,0,5,0,7,0,9,10,11,0,13,14,15,16,17,18,19,0,21,0,23,4,25,26,27,4,29,6,31,6,33,8,35,8,37,12,39,12,41,42,43,44,45,22,47,22,49,50,51,52,53,54,55,56,57,0,59,28,61,62,63,28,65,30,67,68,69,70,71,30,73,32,75,32,77,34,79,80,81,34,83,84,85,36,87,36,89,90,91,92,93,38,95,38,97,98,99,40,101,40,103,104,105,48,107,48,109,74,111,74,113,76,115,76,117,118,119,78,121,78,123,88,125,88,127,128,129,130,131,96,133,134,135,136,137,96,139,140,141,100,143,144,145,100,147,148,149,150,151,108,153,154,155,108,157,158,159,160,161,110,163,110,165,166,167,168,169,170,171,112,173,174,175,176,177,112,179,180,181,114,183,114,185,186,187,188,189,116,191,116,193,194,195,196,197,122,199,122,201,202,203,204,205,206,207,124,209,210,211,212,213,214,215,124,217,218,219,220,221,222,223,126,225,226,227,126,229,230,231,142,233,234,235,142,237,164,239,240,241,164,243,244,245,246,247,184,249,250,251,184,253,254,255,256,257,258,259,190,261,262,263,264,265,190,267,268,269,270,271,272,273,274,275,192,277,278,279,192,281,282,283,284,285,200,287,200,289,290,291,276,293,294,295,296,297,276,299,300,301,280,303,304,305,280,307,288,309,288,311,312,313,298,315,316,317,318,319,298,321,302,323,302,325,326,327,322,329,322,331,332,333,324,335,336,337,338,339,340,341,324,343,344,345,346,347,348,349,328,351,352,353,328,355,356,357,330,359,360,361,330,363] },{ "mechanisms": [{ "indexes": [1,23,59], @@ -375,7 +375,7 @@ "indexes": [1,3,5,7,9,10,11,13,14,15,16,17,18,19,21,23,25,26,27,29,31,33,35,37,39,41,42,43,44,45,47,49,50,51,52,53,54,55,56,57,59,61,62,63,65,67,68,69,70,71,73,75,77,79,80,81,83,84,85,87,89,90,91,92,93,95,97,98,99,101,103,104,105,107,109,111,113,115,117,118,119,121,123,125,127,128,129,130,131,133,134,135,136,137,139,140,141,143,144,145,147,148,149,150,151,153,154,155,157,158,159,160,161,163,165,166,167,168,169,170,171,173,174,175,176,177,179,180,181,183,185,186,187,188,189,191,193,194,195,196,197,199,201,202,203,204,205,206,207,209,210,211,212,213,214,215,217,218,219,220,221,222,223,225,226,227,229,230,231,233,234,235,237,239,240,241,243,244,245,246,247,249,250,251,253,254,255,256,257,258,259,261,262,263,264,265,267,268,269,270,271,272,273,274,275,277,278,279,281,282,283,284,285,287,289,290,291,293,294,295,296,297,299,300,301,303,304,305,307,309,311,312,313,315,316,317,318,319,321,323,325,326,327,329,331,332,333,335,336,337,338,339,340,341,343,344,345,346,347,348,349,351,352,353,355,356,357,359,360,361,363], "name": "pas" }], - "parent_index": [0,0,1,0,3,0,5,0,7,0,9,10,11,0,13,14,15,16,17,18,19,0,21,2,23,4,25,26,27,4,29,6,31,6,33,8,35,8,37,12,39,12,41,42,43,44,45,22,47,22,49,50,51,52,53,54,55,56,57,24,59,28,61,62,63,28,65,30,67,68,69,70,71,30,73,32,75,32,77,34,79,80,81,34,83,84,85,36,87,36,89,90,91,92,93,38,95,38,97,98,99,40,101,40,103,104,105,48,107,48,109,74,111,74,113,76,115,76,117,118,119,78,121,78,123,88,125,88,127,128,129,130,131,96,133,134,135,136,137,96,139,140,141,100,143,144,145,100,147,148,149,150,151,108,153,154,155,108,157,158,159,160,161,110,163,110,165,166,167,168,169,170,171,112,173,174,175,176,177,112,179,180,181,114,183,114,185,186,187,188,189,116,191,116,193,194,195,196,197,122,199,122,201,202,203,204,205,206,207,124,209,210,211,212,213,214,215,124,217,218,219,220,221,222,223,126,225,226,227,126,229,230,231,142,233,234,235,142,237,164,239,240,241,164,243,244,245,246,247,184,249,250,251,184,253,254,255,256,257,258,259,190,261,262,263,264,265,190,267,268,269,270,271,272,273,274,275,192,277,278,279,192,281,282,283,284,285,200,287,200,289,290,291,276,293,294,295,296,297,276,299,300,301,280,303,304,305,280,307,288,309,288,311,312,313,298,315,316,317,318,319,298,321,302,323,302,325,326,327,322,329,322,331,332,333,324,335,336,337,338,339,340,341,324,343,344,345,346,347,348,349,328,351,352,353,328,355,356,357,330,359,360,361,330,363] + "parent_index": [0,0,1,0,3,0,5,0,7,0,9,10,11,0,13,14,15,16,17,18,19,0,21,0,23,4,25,26,27,4,29,6,31,6,33,8,35,8,37,12,39,12,41,42,43,44,45,22,47,22,49,50,51,52,53,54,55,56,57,0,59,28,61,62,63,28,65,30,67,68,69,70,71,30,73,32,75,32,77,34,79,80,81,34,83,84,85,36,87,36,89,90,91,92,93,38,95,38,97,98,99,40,101,40,103,104,105,48,107,48,109,74,111,74,113,76,115,76,117,118,119,78,121,78,123,88,125,88,127,128,129,130,131,96,133,134,135,136,137,96,139,140,141,100,143,144,145,100,147,148,149,150,151,108,153,154,155,108,157,158,159,160,161,110,163,110,165,166,167,168,169,170,171,112,173,174,175,176,177,112,179,180,181,114,183,114,185,186,187,188,189,116,191,116,193,194,195,196,197,122,199,122,201,202,203,204,205,206,207,124,209,210,211,212,213,214,215,124,217,218,219,220,221,222,223,126,225,226,227,126,229,230,231,142,233,234,235,142,237,164,239,240,241,164,243,244,245,246,247,184,249,250,251,184,253,254,255,256,257,258,259,190,261,262,263,264,265,190,267,268,269,270,271,272,273,274,275,192,277,278,279,192,281,282,283,284,285,200,287,200,289,290,291,276,293,294,295,296,297,276,299,300,301,280,303,304,305,280,307,288,309,288,311,312,313,298,315,316,317,318,319,298,321,302,323,302,325,326,327,322,329,322,331,332,333,324,335,336,337,338,339,340,341,324,343,344,345,346,347,348,349,328,351,352,353,328,355,356,357,330,359,360,361,330,363] },{ "mechanisms": [{ "indexes": [1,23,59], @@ -438,7 +438,7 @@ "indexes": [1,3,5,7,9,10,11,13,14,15,16,17,18,19,21,23,25,26,27,29,31,33,35,37,39,41,42,43,44,45,47,49,50,51,52,53,54,55,56,57,59,61,62,63,65,67,68,69,70,71,73,75,77,79,80,81,83,84,85,87,89,90,91,92,93,95,97,98,99,101,103,104,105,107,109,111,113,115,117,118,119,121,123,125,127,128,129,130,131,133,134,135,136,137,139,140,141,143,144,145,147,148,149,150,151,153,154,155,157,158,159,160,161,163,165,166,167,168,169,170,171,173,174,175,176,177,179,180,181,183,185,186,187,188,189,191,193,194,195,196,197,199,201,202,203,204,205,206,207,209,210,211,212,213,214,215,217,218,219,220,221,222,223,225,226,227,229,230,231,233,234,235,237,239,240,241,243,244,245,246,247,249,250,251,253,254,255,256,257,258,259,261,262,263,264,265,267,268,269,270,271,272,273,274,275,277,278,279,281,282,283,284,285,287,289,290,291,293,294,295,296,297,299,300,301,303,304,305,307,309,311,312,313,315,316,317,318,319,321,323,325,326,327,329,331,332,333,335,336,337,338,339,340,341,343,344,345,346,347,348,349,351,352,353,355,356,357,359,360,361,363], "name": "pas" }], - "parent_index": [0,0,1,0,3,0,5,0,7,0,9,10,11,0,13,14,15,16,17,18,19,0,21,2,23,4,25,26,27,4,29,6,31,6,33,8,35,8,37,12,39,12,41,42,43,44,45,22,47,22,49,50,51,52,53,54,55,56,57,24,59,28,61,62,63,28,65,30,67,68,69,70,71,30,73,32,75,32,77,34,79,80,81,34,83,84,85,36,87,36,89,90,91,92,93,38,95,38,97,98,99,40,101,40,103,104,105,48,107,48,109,74,111,74,113,76,115,76,117,118,119,78,121,78,123,88,125,88,127,128,129,130,131,96,133,134,135,136,137,96,139,140,141,100,143,144,145,100,147,148,149,150,151,108,153,154,155,108,157,158,159,160,161,110,163,110,165,166,167,168,169,170,171,112,173,174,175,176,177,112,179,180,181,114,183,114,185,186,187,188,189,116,191,116,193,194,195,196,197,122,199,122,201,202,203,204,205,206,207,124,209,210,211,212,213,214,215,124,217,218,219,220,221,222,223,126,225,226,227,126,229,230,231,142,233,234,235,142,237,164,239,240,241,164,243,244,245,246,247,184,249,250,251,184,253,254,255,256,257,258,259,190,261,262,263,264,265,190,267,268,269,270,271,272,273,274,275,192,277,278,279,192,281,282,283,284,285,200,287,200,289,290,291,276,293,294,295,296,297,276,299,300,301,280,303,304,305,280,307,288,309,288,311,312,313,298,315,316,317,318,319,298,321,302,323,302,325,326,327,322,329,322,331,332,333,324,335,336,337,338,339,340,341,324,343,344,345,346,347,348,349,328,351,352,353,328,355,356,357,330,359,360,361,330,363] + "parent_index": [0,0,1,0,3,0,5,0,7,0,9,10,11,0,13,14,15,16,17,18,19,0,21,0,23,4,25,26,27,4,29,6,31,6,33,8,35,8,37,12,39,12,41,42,43,44,45,22,47,22,49,50,51,52,53,54,55,56,57,0,59,28,61,62,63,28,65,30,67,68,69,70,71,30,73,32,75,32,77,34,79,80,81,34,83,84,85,36,87,36,89,90,91,92,93,38,95,38,97,98,99,40,101,40,103,104,105,48,107,48,109,74,111,74,113,76,115,76,117,118,119,78,121,78,123,88,125,88,127,128,129,130,131,96,133,134,135,136,137,96,139,140,141,100,143,144,145,100,147,148,149,150,151,108,153,154,155,108,157,158,159,160,161,110,163,110,165,166,167,168,169,170,171,112,173,174,175,176,177,112,179,180,181,114,183,114,185,186,187,188,189,116,191,116,193,194,195,196,197,122,199,122,201,202,203,204,205,206,207,124,209,210,211,212,213,214,215,124,217,218,219,220,221,222,223,126,225,226,227,126,229,230,231,142,233,234,235,142,237,164,239,240,241,164,243,244,245,246,247,184,249,250,251,184,253,254,255,256,257,258,259,190,261,262,263,264,265,190,267,268,269,270,271,272,273,274,275,192,277,278,279,192,281,282,283,284,285,200,287,200,289,290,291,276,293,294,295,296,297,276,299,300,301,280,303,304,305,280,307,288,309,288,311,312,313,298,315,316,317,318,319,298,321,302,323,302,325,326,327,322,329,322,331,332,333,324,335,336,337,338,339,340,341,324,343,344,345,346,347,348,349,328,351,352,353,328,355,356,357,330,359,360,361,330,363] },{ "mechanisms": [{ "indexes": [1,23,59], @@ -501,7 +501,7 @@ "indexes": [1,3,5,7,9,10,11,13,14,15,16,17,18,19,21,23,25,26,27,29,31,33,35,37,39,41,42,43,44,45,47,49,50,51,52,53,54,55,56,57,59,61,62,63,65,67,68,69,70,71,73,75,77,79,80,81,83,84,85,87,89,90,91,92,93,95,97,98,99,101,103,104,105,107,109,111,113,115,117,118,119,121,123,125,127,128,129,130,131,133,134,135,136,137,139,140,141,143,144,145,147,148,149,150,151,153,154,155,157,158,159,160,161,163,165,166,167,168,169,170,171,173,174,175,176,177,179,180,181,183,185,186,187,188,189,191,193,194,195,196,197,199,201,202,203,204,205,206,207,209,210,211,212,213,214,215,217,218,219,220,221,222,223,225,226,227,229,230,231,233,234,235,237,239,240,241,243,244,245,246,247,249,250,251,253,254,255,256,257,258,259,261,262,263,264,265,267,268,269,270,271,272,273,274,275,277,278,279,281,282,283,284,285,287,289,290,291,293,294,295,296,297,299,300,301,303,304,305,307,309,311,312,313,315,316,317,318,319,321,323,325,326,327,329,331,332,333,335,336,337,338,339,340,341,343,344,345,346,347,348,349,351,352,353,355,356,357,359,360,361,363], "name": "pas" }], - "parent_index": [0,0,1,0,3,0,5,0,7,0,9,10,11,0,13,14,15,16,17,18,19,0,21,2,23,4,25,26,27,4,29,6,31,6,33,8,35,8,37,12,39,12,41,42,43,44,45,22,47,22,49,50,51,52,53,54,55,56,57,24,59,28,61,62,63,28,65,30,67,68,69,70,71,30,73,32,75,32,77,34,79,80,81,34,83,84,85,36,87,36,89,90,91,92,93,38,95,38,97,98,99,40,101,40,103,104,105,48,107,48,109,74,111,74,113,76,115,76,117,118,119,78,121,78,123,88,125,88,127,128,129,130,131,96,133,134,135,136,137,96,139,140,141,100,143,144,145,100,147,148,149,150,151,108,153,154,155,108,157,158,159,160,161,110,163,110,165,166,167,168,169,170,171,112,173,174,175,176,177,112,179,180,181,114,183,114,185,186,187,188,189,116,191,116,193,194,195,196,197,122,199,122,201,202,203,204,205,206,207,124,209,210,211,212,213,214,215,124,217,218,219,220,221,222,223,126,225,226,227,126,229,230,231,142,233,234,235,142,237,164,239,240,241,164,243,244,245,246,247,184,249,250,251,184,253,254,255,256,257,258,259,190,261,262,263,264,265,190,267,268,269,270,271,272,273,274,275,192,277,278,279,192,281,282,283,284,285,200,287,200,289,290,291,276,293,294,295,296,297,276,299,300,301,280,303,304,305,280,307,288,309,288,311,312,313,298,315,316,317,318,319,298,321,302,323,302,325,326,327,322,329,322,331,332,333,324,335,336,337,338,339,340,341,324,343,344,345,346,347,348,349,328,351,352,353,328,355,356,357,330,359,360,361,330,363] + "parent_index": [0,0,1,0,3,0,5,0,7,0,9,10,11,0,13,14,15,16,17,18,19,0,21,0,23,4,25,26,27,4,29,6,31,6,33,8,35,8,37,12,39,12,41,42,43,44,45,22,47,22,49,50,51,52,53,54,55,56,57,0,59,28,61,62,63,28,65,30,67,68,69,70,71,30,73,32,75,32,77,34,79,80,81,34,83,84,85,36,87,36,89,90,91,92,93,38,95,38,97,98,99,40,101,40,103,104,105,48,107,48,109,74,111,74,113,76,115,76,117,118,119,78,121,78,123,88,125,88,127,128,129,130,131,96,133,134,135,136,137,96,139,140,141,100,143,144,145,100,147,148,149,150,151,108,153,154,155,108,157,158,159,160,161,110,163,110,165,166,167,168,169,170,171,112,173,174,175,176,177,112,179,180,181,114,183,114,185,186,187,188,189,116,191,116,193,194,195,196,197,122,199,122,201,202,203,204,205,206,207,124,209,210,211,212,213,214,215,124,217,218,219,220,221,222,223,126,225,226,227,126,229,230,231,142,233,234,235,142,237,164,239,240,241,164,243,244,245,246,247,184,249,250,251,184,253,254,255,256,257,258,259,190,261,262,263,264,265,190,267,268,269,270,271,272,273,274,275,192,277,278,279,192,281,282,283,284,285,200,287,200,289,290,291,276,293,294,295,296,297,276,299,300,301,280,303,304,305,280,307,288,309,288,311,312,313,298,315,316,317,318,319,298,321,302,323,302,325,326,327,322,329,322,331,332,333,324,335,336,337,338,339,340,341,324,343,344,345,346,347,348,349,328,351,352,353,328,355,356,357,330,359,360,361,330,363] },{ "mechanisms": [{ "indexes": [1,19,57], @@ -564,7 +564,7 @@ "indexes": [1,3,5,7,9,10,11,12,13,15,17,19,21,22,23,25,27,29,31,33,34,35,37,39,41,42,43,45,47,48,49,50,51,52,53,55,57,59,60,61,63,65,66,67,69,71,73,74,75,77,78,79,81,83,85,86,87,88,89,91,93,95,97,99,100,101,102,103,105,107,109,110,111,113,115,116,117,119,121,123,124,125,127,128,129,131,133,135,137,138,139,141,143,144,145,147,149,151,153,154,155,157,159,161,162,163,165,166,167,169,170,171,173,175,176,177,179,180,181,182,183,185,186,187,189,191,192,193,194,195,197,198,199,201,203,205,207,208,209,211,212,213,215,216,217,219,220,221,223,225,226,227,229,230,231,232,233,235,237,239,241,243,244,245,247,249,251,253,254,255,256,257,259,261,262,263,264,265,267,269,271,273,274,275,277,279,281,283,285,286,287,289,291,292,293,295,297,299,300,301,302,303,305,306,307,308,309,310,311,313,314,315,317,318,319,320,321,322,323,324,325,327,328,329,331,332,333,335,337,338,339,341,343,345,346,347,348,349,351,353,355,357,359,360,361], "name": "pas" }], - "parent_index": [0,0,1,0,3,0,5,0,7,0,9,10,11,12,13,0,15,0,17,2,19,4,21,22,23,4,25,6,27,6,29,8,31,8,33,34,35,14,37,14,39,16,41,42,43,16,45,18,47,48,49,50,51,52,53,18,55,20,57,24,59,60,61,24,63,26,65,66,67,26,69,28,71,28,73,74,75,30,77,78,79,30,81,32,83,32,85,86,87,88,89,36,91,36,93,46,95,46,97,56,99,100,101,102,103,56,105,64,107,64,109,110,111,68,113,68,115,116,117,70,119,70,121,72,123,124,125,72,127,128,129,76,131,76,133,80,135,80,137,138,139,82,141,82,143,144,145,92,147,92,149,94,151,94,153,154,155,96,157,96,159,104,161,162,163,104,165,166,167,106,169,170,171,106,173,120,175,176,177,120,179,180,181,182,183,122,185,186,187,122,189,126,191,192,193,194,195,126,197,198,199,132,201,132,203,140,205,140,207,208,209,142,211,212,213,142,215,216,217,146,219,220,221,146,223,152,225,226,227,152,229,230,231,232,233,160,235,160,237,172,239,172,241,174,243,244,245,174,247,188,249,188,251,190,253,254,255,256,257,190,259,218,261,262,263,264,265,218,267,224,269,224,271,246,273,274,275,246,277,248,279,248,281,260,283,260,285,286,287,278,289,278,291,292,293,282,295,282,297,288,299,300,301,302,303,288,305,306,307,308,309,310,311,304,313,314,315,304,317,318,319,320,321,322,323,324,325,312,327,328,329,312,331,332,333,334,335,334,337,338,339,340,341,340,343,342,345,346,347,348,349,342,351,344,353,344,355,356,357,356,359,360,361] + "parent_index": [0,0,1,0,3,0,5,0,7,0,9,10,11,12,13,0,15,0,17,0,19,4,21,22,23,4,25,6,27,6,29,8,31,8,33,34,35,14,37,14,39,16,41,42,43,16,45,18,47,48,49,50,51,52,53,18,55,0,57,24,59,60,61,24,63,26,65,66,67,26,69,28,71,28,73,74,75,30,77,78,79,30,81,32,83,32,85,86,87,88,89,36,91,36,93,46,95,46,97,56,99,100,101,102,103,56,105,64,107,64,109,110,111,68,113,68,115,116,117,70,119,70,121,72,123,124,125,72,127,128,129,76,131,76,133,80,135,80,137,138,139,82,141,82,143,144,145,92,147,92,149,94,151,94,153,154,155,96,157,96,159,104,161,162,163,104,165,166,167,106,169,170,171,106,173,120,175,176,177,120,179,180,181,182,183,122,185,186,187,122,189,126,191,192,193,194,195,126,197,198,199,132,201,132,203,140,205,140,207,208,209,142,211,212,213,142,215,216,217,146,219,220,221,146,223,152,225,226,227,152,229,230,231,232,233,160,235,160,237,172,239,172,241,174,243,244,245,174,247,188,249,188,251,190,253,254,255,256,257,190,259,218,261,262,263,264,265,218,267,224,269,224,271,246,273,274,275,246,277,248,279,248,281,260,283,260,285,286,287,278,289,278,291,292,293,282,295,282,297,288,299,300,301,302,303,288,305,306,307,308,309,310,311,304,313,314,315,304,317,318,319,320,321,322,323,324,325,312,327,328,329,312,331,332,333,334,335,334,337,338,339,340,341,340,343,342,345,346,347,348,349,342,351,344,353,344,355,356,357,356,359,360,361] },{ "mechanisms": [{ "indexes": [1,19,57], @@ -627,7 +627,7 @@ "indexes": [1,3,5,7,9,10,11,12,13,15,17,19,21,22,23,25,27,29,31,33,34,35,37,39,41,42,43,45,47,48,49,50,51,52,53,55,57,59,60,61,63,65,66,67,69,71,73,74,75,77,78,79,81,83,85,86,87,88,89,91,93,95,97,99,100,101,102,103,105,107,109,110,111,113,115,116,117,119,121,123,124,125,127,128,129,131,133,135,137,138,139,141,143,144,145,147,149,151,153,154,155,157,159,161,162,163,165,166,167,169,170,171,173,175,176,177,179,180,181,182,183,185,186,187,189,191,192,193,194,195,197,198,199,201,203,205,207,208,209,211,212,213,215,216,217,219,220,221,223,225,226,227,229,230,231,232,233,235,237,239,241,243,244,245,247,249,251,253,254,255,256,257,259,261,262,263,264,265,267,269,271,273,274,275,277,279,281,283,285,286,287,289,291,292,293,295,297,299,300,301,302,303,305,306,307,308,309,310,311,313,314,315,317,318,319,320,321,322,323,324,325,327,328,329,331,332,333,335,337,338,339,341,343,345,346,347,348,349,351,353,355,357,359,360,361], "name": "pas" }], - "parent_index": [0,0,1,0,3,0,5,0,7,0,9,10,11,12,13,0,15,0,17,2,19,4,21,22,23,4,25,6,27,6,29,8,31,8,33,34,35,14,37,14,39,16,41,42,43,16,45,18,47,48,49,50,51,52,53,18,55,20,57,24,59,60,61,24,63,26,65,66,67,26,69,28,71,28,73,74,75,30,77,78,79,30,81,32,83,32,85,86,87,88,89,36,91,36,93,46,95,46,97,56,99,100,101,102,103,56,105,64,107,64,109,110,111,68,113,68,115,116,117,70,119,70,121,72,123,124,125,72,127,128,129,76,131,76,133,80,135,80,137,138,139,82,141,82,143,144,145,92,147,92,149,94,151,94,153,154,155,96,157,96,159,104,161,162,163,104,165,166,167,106,169,170,171,106,173,120,175,176,177,120,179,180,181,182,183,122,185,186,187,122,189,126,191,192,193,194,195,126,197,198,199,132,201,132,203,140,205,140,207,208,209,142,211,212,213,142,215,216,217,146,219,220,221,146,223,152,225,226,227,152,229,230,231,232,233,160,235,160,237,172,239,172,241,174,243,244,245,174,247,188,249,188,251,190,253,254,255,256,257,190,259,218,261,262,263,264,265,218,267,224,269,224,271,246,273,274,275,246,277,248,279,248,281,260,283,260,285,286,287,278,289,278,291,292,293,282,295,282,297,288,299,300,301,302,303,288,305,306,307,308,309,310,311,304,313,314,315,304,317,318,319,320,321,322,323,324,325,312,327,328,329,312,331,332,333,334,335,334,337,338,339,340,341,340,343,342,345,346,347,348,349,342,351,344,353,344,355,356,357,356,359,360,361] + "parent_index": [0,0,1,0,3,0,5,0,7,0,9,10,11,12,13,0,15,0,17,0,19,4,21,22,23,4,25,6,27,6,29,8,31,8,33,34,35,14,37,14,39,16,41,42,43,16,45,18,47,48,49,50,51,52,53,18,55,0,57,24,59,60,61,24,63,26,65,66,67,26,69,28,71,28,73,74,75,30,77,78,79,30,81,32,83,32,85,86,87,88,89,36,91,36,93,46,95,46,97,56,99,100,101,102,103,56,105,64,107,64,109,110,111,68,113,68,115,116,117,70,119,70,121,72,123,124,125,72,127,128,129,76,131,76,133,80,135,80,137,138,139,82,141,82,143,144,145,92,147,92,149,94,151,94,153,154,155,96,157,96,159,104,161,162,163,104,165,166,167,106,169,170,171,106,173,120,175,176,177,120,179,180,181,182,183,122,185,186,187,122,189,126,191,192,193,194,195,126,197,198,199,132,201,132,203,140,205,140,207,208,209,142,211,212,213,142,215,216,217,146,219,220,221,146,223,152,225,226,227,152,229,230,231,232,233,160,235,160,237,172,239,172,241,174,243,244,245,174,247,188,249,188,251,190,253,254,255,256,257,190,259,218,261,262,263,264,265,218,267,224,269,224,271,246,273,274,275,246,277,248,279,248,281,260,283,260,285,286,287,278,289,278,291,292,293,282,295,282,297,288,299,300,301,302,303,288,305,306,307,308,309,310,311,304,313,314,315,304,317,318,319,320,321,322,323,324,325,312,327,328,329,312,331,332,333,334,335,334,337,338,339,340,341,340,343,342,345,346,347,348,349,342,351,344,353,344,355,356,357,356,359,360,361] },{ "mechanisms": [{ "indexes": [1,19,57], @@ -690,7 +690,7 @@ "indexes": [1,3,5,7,9,10,11,12,13,15,17,19,21,22,23,25,27,29,31,33,34,35,37,39,41,42,43,45,47,48,49,50,51,52,53,55,57,59,60,61,63,65,66,67,69,71,73,74,75,77,78,79,81,83,85,86,87,88,89,91,93,95,97,99,100,101,102,103,105,107,109,110,111,113,115,116,117,119,121,123,124,125,127,128,129,131,133,135,137,138,139,141,143,144,145,147,149,151,153,154,155,157,159,161,162,163,165,166,167,169,170,171,173,175,176,177,179,180,181,182,183,185,186,187,189,191,192,193,194,195,197,198,199,201,203,205,207,208,209,211,212,213,215,216,217,219,220,221,223,225,226,227,229,230,231,232,233,235,237,239,241,243,244,245,247,249,251,253,254,255,256,257,259,261,262,263,264,265,267,269,271,273,274,275,277,279,281,283,285,286,287,289,291,292,293,295,297,299,300,301,302,303,305,306,307,308,309,310,311,313,314,315,317,318,319,320,321,322,323,324,325,327,328,329,331,332,333,335,337,338,339,341,343,345,346,347,348,349,351,353,355,357,359,360,361], "name": "pas" }], - "parent_index": [0,0,1,0,3,0,5,0,7,0,9,10,11,12,13,0,15,0,17,2,19,4,21,22,23,4,25,6,27,6,29,8,31,8,33,34,35,14,37,14,39,16,41,42,43,16,45,18,47,48,49,50,51,52,53,18,55,20,57,24,59,60,61,24,63,26,65,66,67,26,69,28,71,28,73,74,75,30,77,78,79,30,81,32,83,32,85,86,87,88,89,36,91,36,93,46,95,46,97,56,99,100,101,102,103,56,105,64,107,64,109,110,111,68,113,68,115,116,117,70,119,70,121,72,123,124,125,72,127,128,129,76,131,76,133,80,135,80,137,138,139,82,141,82,143,144,145,92,147,92,149,94,151,94,153,154,155,96,157,96,159,104,161,162,163,104,165,166,167,106,169,170,171,106,173,120,175,176,177,120,179,180,181,182,183,122,185,186,187,122,189,126,191,192,193,194,195,126,197,198,199,132,201,132,203,140,205,140,207,208,209,142,211,212,213,142,215,216,217,146,219,220,221,146,223,152,225,226,227,152,229,230,231,232,233,160,235,160,237,172,239,172,241,174,243,244,245,174,247,188,249,188,251,190,253,254,255,256,257,190,259,218,261,262,263,264,265,218,267,224,269,224,271,246,273,274,275,246,277,248,279,248,281,260,283,260,285,286,287,278,289,278,291,292,293,282,295,282,297,288,299,300,301,302,303,288,305,306,307,308,309,310,311,304,313,314,315,304,317,318,319,320,321,322,323,324,325,312,327,328,329,312,331,332,333,334,335,334,337,338,339,340,341,340,343,342,345,346,347,348,349,342,351,344,353,344,355,356,357,356,359,360,361] + "parent_index": [0,0,1,0,3,0,5,0,7,0,9,10,11,12,13,0,15,0,17,0,19,4,21,22,23,4,25,6,27,6,29,8,31,8,33,34,35,14,37,14,39,16,41,42,43,16,45,18,47,48,49,50,51,52,53,18,55,0,57,24,59,60,61,24,63,26,65,66,67,26,69,28,71,28,73,74,75,30,77,78,79,30,81,32,83,32,85,86,87,88,89,36,91,36,93,46,95,46,97,56,99,100,101,102,103,56,105,64,107,64,109,110,111,68,113,68,115,116,117,70,119,70,121,72,123,124,125,72,127,128,129,76,131,76,133,80,135,80,137,138,139,82,141,82,143,144,145,92,147,92,149,94,151,94,153,154,155,96,157,96,159,104,161,162,163,104,165,166,167,106,169,170,171,106,173,120,175,176,177,120,179,180,181,182,183,122,185,186,187,122,189,126,191,192,193,194,195,126,197,198,199,132,201,132,203,140,205,140,207,208,209,142,211,212,213,142,215,216,217,146,219,220,221,146,223,152,225,226,227,152,229,230,231,232,233,160,235,160,237,172,239,172,241,174,243,244,245,174,247,188,249,188,251,190,253,254,255,256,257,190,259,218,261,262,263,264,265,218,267,224,269,224,271,246,273,274,275,246,277,248,279,248,281,260,283,260,285,286,287,278,289,278,291,292,293,282,295,282,297,288,299,300,301,302,303,288,305,306,307,308,309,310,311,304,313,314,315,304,317,318,319,320,321,322,323,324,325,312,327,328,329,312,331,332,333,334,335,334,337,338,339,340,341,340,343,342,345,346,347,348,349,342,351,344,353,344,355,356,357,356,359,360,361] },{ "mechanisms": [{ "indexes": [1,19,57], @@ -753,7 +753,7 @@ "indexes": [1,3,5,7,9,10,11,12,13,15,17,19,21,22,23,25,27,29,31,33,34,35,37,39,41,42,43,45,47,48,49,50,51,52,53,55,57,59,60,61,63,65,66,67,69,71,73,74,75,77,78,79,81,83,85,86,87,88,89,91,93,95,97,99,100,101,102,103,105,107,109,110,111,113,115,116,117,119,121,123,124,125,127,128,129,131,133,135,137,138,139,141,143,144,145,147,149,151,153,154,155,157,159,161,162,163,165,166,167,169,170,171,173,175,176,177,179,180,181,182,183,185,186,187,189,191,192,193,194,195,197,198,199,201,203,205,207,208,209,211,212,213,215,216,217,219,220,221,223,225,226,227,229,230,231,232,233,235,237,239,241,243,244,245,247,249,251,253,254,255,256,257,259,261,262,263,264,265,267,269,271,273,274,275,277,279,281,283,285,286,287,289,291,292,293,295,297,299,300,301,302,303,305,306,307,308,309,310,311,313,314,315,317,318,319,320,321,322,323,324,325,327,328,329,331,332,333,335,337,338,339,341,343,345,346,347,348,349,351,353,355,357,359,360,361], "name": "pas" }], - "parent_index": [0,0,1,0,3,0,5,0,7,0,9,10,11,12,13,0,15,0,17,2,19,4,21,22,23,4,25,6,27,6,29,8,31,8,33,34,35,14,37,14,39,16,41,42,43,16,45,18,47,48,49,50,51,52,53,18,55,20,57,24,59,60,61,24,63,26,65,66,67,26,69,28,71,28,73,74,75,30,77,78,79,30,81,32,83,32,85,86,87,88,89,36,91,36,93,46,95,46,97,56,99,100,101,102,103,56,105,64,107,64,109,110,111,68,113,68,115,116,117,70,119,70,121,72,123,124,125,72,127,128,129,76,131,76,133,80,135,80,137,138,139,82,141,82,143,144,145,92,147,92,149,94,151,94,153,154,155,96,157,96,159,104,161,162,163,104,165,166,167,106,169,170,171,106,173,120,175,176,177,120,179,180,181,182,183,122,185,186,187,122,189,126,191,192,193,194,195,126,197,198,199,132,201,132,203,140,205,140,207,208,209,142,211,212,213,142,215,216,217,146,219,220,221,146,223,152,225,226,227,152,229,230,231,232,233,160,235,160,237,172,239,172,241,174,243,244,245,174,247,188,249,188,251,190,253,254,255,256,257,190,259,218,261,262,263,264,265,218,267,224,269,224,271,246,273,274,275,246,277,248,279,248,281,260,283,260,285,286,287,278,289,278,291,292,293,282,295,282,297,288,299,300,301,302,303,288,305,306,307,308,309,310,311,304,313,314,315,304,317,318,319,320,321,322,323,324,325,312,327,328,329,312,331,332,333,334,335,334,337,338,339,340,341,340,343,342,345,346,347,348,349,342,351,344,353,344,355,356,357,356,359,360,361] + "parent_index": [0,0,1,0,3,0,5,0,7,0,9,10,11,12,13,0,15,0,17,0,19,4,21,22,23,4,25,6,27,6,29,8,31,8,33,34,35,14,37,14,39,16,41,42,43,16,45,18,47,48,49,50,51,52,53,18,55,0,57,24,59,60,61,24,63,26,65,66,67,26,69,28,71,28,73,74,75,30,77,78,79,30,81,32,83,32,85,86,87,88,89,36,91,36,93,46,95,46,97,56,99,100,101,102,103,56,105,64,107,64,109,110,111,68,113,68,115,116,117,70,119,70,121,72,123,124,125,72,127,128,129,76,131,76,133,80,135,80,137,138,139,82,141,82,143,144,145,92,147,92,149,94,151,94,153,154,155,96,157,96,159,104,161,162,163,104,165,166,167,106,169,170,171,106,173,120,175,176,177,120,179,180,181,182,183,122,185,186,187,122,189,126,191,192,193,194,195,126,197,198,199,132,201,132,203,140,205,140,207,208,209,142,211,212,213,142,215,216,217,146,219,220,221,146,223,152,225,226,227,152,229,230,231,232,233,160,235,160,237,172,239,172,241,174,243,244,245,174,247,188,249,188,251,190,253,254,255,256,257,190,259,218,261,262,263,264,265,218,267,224,269,224,271,246,273,274,275,246,277,248,279,248,281,260,283,260,285,286,287,278,289,278,291,292,293,282,295,282,297,288,299,300,301,302,303,288,305,306,307,308,309,310,311,304,313,314,315,304,317,318,319,320,321,322,323,324,325,312,327,328,329,312,331,332,333,334,335,334,337,338,339,340,341,340,343,342,345,346,347,348,349,342,351,344,353,344,355,356,357,356,359,360,361] },{ "mechanisms": [{ "indexes": [1,27,67], @@ -816,7 +816,7 @@ "indexes": [1,3,5,7,9,10,11,12,13,14,15,17,19,20,21,22,23,24,25,27,29,31,33,34,35,36,37,38,39,41,43,44,45,46,47,49,50,51,52,53,55,56,57,58,59,60,61,62,63,65,67,69,71,73,74,75,76,77,78,79,81,82,83,84,85,87,88,89,90,91,93,95,96,97,98,99,100,101,103,104,105,106,107,108,109,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,143,144,145,147,149,150,151,152,153,154,155,157,159,160,161,162,163,165,166,167,168,169,170,171,172,173,175,176,177,178,179,180,181,183,185,187,188,189,190,191,193,194,195], "name": "pas" }], - "parent_index": [0,0,1,0,3,0,5,0,7,0,9,10,11,12,13,14,15,0,17,0,19,20,21,22,23,24,25,2,27,4,29,4,31,6,33,34,35,36,37,38,39,6,41,8,43,44,45,46,47,8,49,50,51,52,53,18,55,56,57,58,59,60,61,62,63,18,65,28,67,30,69,30,71,32,73,74,75,76,77,78,79,32,81,82,83,84,85,42,87,88,89,90,91,42,93,66,95,96,97,98,99,100,101,66,103,104,105,106,107,108,109,70,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,70,143,144,145,72,147,72,149,150,151,152,153,154,155,80,157,80,159,160,161,162,163,142,165,166,167,168,169,170,171,172,173,142,175,176,177,178,179,180,181,146,183,146,185,148,187,188,189,190,191,148,193,194,195] + "parent_index": [0,0,1,0,3,0,5,0,7,0,9,10,11,12,13,14,15,0,17,0,19,20,21,22,23,24,25,0,27,4,29,4,31,6,33,34,35,36,37,38,39,6,41,8,43,44,45,46,47,8,49,50,51,52,53,18,55,56,57,58,59,60,61,62,63,18,65,0,67,30,69,30,71,32,73,74,75,76,77,78,79,32,81,82,83,84,85,42,87,88,89,90,91,42,93,66,95,96,97,98,99,100,101,66,103,104,105,106,107,108,109,70,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,70,143,144,145,72,147,72,149,150,151,152,153,154,155,80,157,80,159,160,161,162,163,142,165,166,167,168,169,170,171,172,173,142,175,176,177,178,179,180,181,146,183,146,185,148,187,188,189,190,191,148,193,194,195] },{ "mechanisms": [{ "indexes": [1,27,67], @@ -879,7 +879,7 @@ "indexes": [1,3,5,7,9,10,11,12,13,14,15,17,19,20,21,22,23,24,25,27,29,31,33,34,35,36,37,38,39,41,43,44,45,46,47,49,50,51,52,53,55,56,57,58,59,60,61,62,63,65,67,69,71,73,74,75,76,77,78,79,81,82,83,84,85,87,88,89,90,91,93,95,96,97,98,99,100,101,103,104,105,106,107,108,109,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,143,144,145,147,149,150,151,152,153,154,155,157,159,160,161,162,163,165,166,167,168,169,170,171,172,173,175,176,177,178,179,180,181,183,185,187,188,189,190,191,193,194,195], "name": "pas" }], - "parent_index": [0,0,1,0,3,0,5,0,7,0,9,10,11,12,13,14,15,0,17,0,19,20,21,22,23,24,25,2,27,4,29,4,31,6,33,34,35,36,37,38,39,6,41,8,43,44,45,46,47,8,49,50,51,52,53,18,55,56,57,58,59,60,61,62,63,18,65,28,67,30,69,30,71,32,73,74,75,76,77,78,79,32,81,82,83,84,85,42,87,88,89,90,91,42,93,66,95,96,97,98,99,100,101,66,103,104,105,106,107,108,109,70,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,70,143,144,145,72,147,72,149,150,151,152,153,154,155,80,157,80,159,160,161,162,163,142,165,166,167,168,169,170,171,172,173,142,175,176,177,178,179,180,181,146,183,146,185,148,187,188,189,190,191,148,193,194,195] + "parent_index": [0,0,1,0,3,0,5,0,7,0,9,10,11,12,13,14,15,0,17,0,19,20,21,22,23,24,25,0,27,4,29,4,31,6,33,34,35,36,37,38,39,6,41,8,43,44,45,46,47,8,49,50,51,52,53,18,55,56,57,58,59,60,61,62,63,18,65,0,67,30,69,30,71,32,73,74,75,76,77,78,79,32,81,82,83,84,85,42,87,88,89,90,91,42,93,66,95,96,97,98,99,100,101,66,103,104,105,106,107,108,109,70,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,70,143,144,145,72,147,72,149,150,151,152,153,154,155,80,157,80,159,160,161,162,163,142,165,166,167,168,169,170,171,172,173,142,175,176,177,178,179,180,181,146,183,146,185,148,187,188,189,190,191,148,193,194,195] },{ "mechanisms": [{ "indexes": [1,27,67], @@ -942,7 +942,7 @@ "indexes": [1,3,5,7,9,10,11,12,13,14,15,17,19,20,21,22,23,24,25,27,29,31,33,34,35,36,37,38,39,41,43,44,45,46,47,49,50,51,52,53,55,56,57,58,59,60,61,62,63,65,67,69,71,73,74,75,76,77,78,79,81,82,83,84,85,87,88,89,90,91,93,95,96,97,98,99,100,101,103,104,105,106,107,108,109,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,143,144,145,147,149,150,151,152,153,154,155,157,159,160,161,162,163,165,166,167,168,169,170,171,172,173,175,176,177,178,179,180,181,183,185,187,188,189,190,191,193,194,195], "name": "pas" }], - "parent_index": [0,0,1,0,3,0,5,0,7,0,9,10,11,12,13,14,15,0,17,0,19,20,21,22,23,24,25,2,27,4,29,4,31,6,33,34,35,36,37,38,39,6,41,8,43,44,45,46,47,8,49,50,51,52,53,18,55,56,57,58,59,60,61,62,63,18,65,28,67,30,69,30,71,32,73,74,75,76,77,78,79,32,81,82,83,84,85,42,87,88,89,90,91,42,93,66,95,96,97,98,99,100,101,66,103,104,105,106,107,108,109,70,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,70,143,144,145,72,147,72,149,150,151,152,153,154,155,80,157,80,159,160,161,162,163,142,165,166,167,168,169,170,171,172,173,142,175,176,177,178,179,180,181,146,183,146,185,148,187,188,189,190,191,148,193,194,195] + "parent_index": [0,0,1,0,3,0,5,0,7,0,9,10,11,12,13,14,15,0,17,0,19,20,21,22,23,24,25,0,27,4,29,4,31,6,33,34,35,36,37,38,39,6,41,8,43,44,45,46,47,8,49,50,51,52,53,18,55,56,57,58,59,60,61,62,63,18,65,0,67,30,69,30,71,32,73,74,75,76,77,78,79,32,81,82,83,84,85,42,87,88,89,90,91,42,93,66,95,96,97,98,99,100,101,66,103,104,105,106,107,108,109,70,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,70,143,144,145,72,147,72,149,150,151,152,153,154,155,80,157,80,159,160,161,162,163,142,165,166,167,168,169,170,171,172,173,142,175,176,177,178,179,180,181,146,183,146,185,148,187,188,189,190,191,148,193,194,195] },{ "mechanisms": [{ "indexes": [1,27,67], @@ -1005,7 +1005,7 @@ "indexes": [1,3,5,7,9,10,11,12,13,14,15,17,19,20,21,22,23,24,25,27,29,31,33,34,35,36,37,38,39,41,43,44,45,46,47,49,50,51,52,53,55,56,57,58,59,60,61,62,63,65,67,69,71,73,74,75,76,77,78,79,81,82,83,84,85,87,88,89,90,91,93,95,96,97,98,99,100,101,103,104,105,106,107,108,109,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,143,144,145,147,149,150,151,152,153,154,155,157,159,160,161,162,163,165,166,167,168,169,170,171,172,173,175,176,177,178,179,180,181,183,185,187,188,189,190,191,193,194,195], "name": "pas" }], - "parent_index": [0,0,1,0,3,0,5,0,7,0,9,10,11,12,13,14,15,0,17,0,19,20,21,22,23,24,25,2,27,4,29,4,31,6,33,34,35,36,37,38,39,6,41,8,43,44,45,46,47,8,49,50,51,52,53,18,55,56,57,58,59,60,61,62,63,18,65,28,67,30,69,30,71,32,73,74,75,76,77,78,79,32,81,82,83,84,85,42,87,88,89,90,91,42,93,66,95,96,97,98,99,100,101,66,103,104,105,106,107,108,109,70,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,70,143,144,145,72,147,72,149,150,151,152,153,154,155,80,157,80,159,160,161,162,163,142,165,166,167,168,169,170,171,172,173,142,175,176,177,178,179,180,181,146,183,146,185,148,187,188,189,190,191,148,193,194,195] + "parent_index": [0,0,1,0,3,0,5,0,7,0,9,10,11,12,13,14,15,0,17,0,19,20,21,22,23,24,25,0,27,4,29,4,31,6,33,34,35,36,37,38,39,6,41,8,43,44,45,46,47,8,49,50,51,52,53,18,55,56,57,58,59,60,61,62,63,18,65,0,67,30,69,30,71,32,73,74,75,76,77,78,79,32,81,82,83,84,85,42,87,88,89,90,91,42,93,66,95,96,97,98,99,100,101,66,103,104,105,106,107,108,109,70,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,70,143,144,145,72,147,72,149,150,151,152,153,154,155,80,157,80,159,160,161,162,163,142,165,166,167,168,169,170,171,172,173,142,175,176,177,178,179,180,181,146,183,146,185,148,187,188,189,190,191,148,193,194,195] },{ "mechanisms": [{ "indexes": [1,19,57], @@ -1068,7 +1068,7 @@ "indexes": [1,3,5,7,9,11,12,13,14,15,17,19,21,23,25,26,27,28,29,31,32,33,34,35,37,39,40,41,43,45,46,47,48,49,50,51,53,55,57,59,61,63,64,65,66,67,69,70,71,73,75,77,79,81,83,84,85,87,89,91,92,93,94,95,97,98,99,100,101,103,105,107,108,109,110,111,113,114,115,116,117,119,120,121,122,123,125,126,127,128,129,131,133,134,135,137,138,139,140,141,142,143,145,147,148,149,150,151,153,154,155,157,159,160,161,163,164,165,166,167,168,169,170,171,173,174,175,177,178,179,180,181,183,184,185,186,187,189,190,191,193,194,195,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,217,218,219,221,222,223,225,226,227,228,229,231,233,234,235,237,238,239,241,243,245,247,249], "name": "pas" }], - "parent_index": [0,0,1,0,3,0,5,0,7,0,9,0,11,12,13,14,15,0,17,2,19,4,21,4,23,6,25,26,27,28,29,6,31,32,33,34,35,8,37,8,39,40,41,10,43,10,45,46,47,48,49,50,51,18,53,18,55,20,57,22,59,22,61,24,63,64,65,66,67,24,69,70,71,30,73,30,75,36,77,36,79,38,81,38,83,84,85,42,87,42,89,44,91,92,93,94,95,44,97,98,99,100,101,52,103,52,105,54,107,108,109,110,111,54,113,114,115,116,117,56,119,120,121,122,123,56,125,126,127,128,129,60,131,60,133,134,135,62,137,138,139,140,141,142,143,62,145,82,147,148,149,150,151,82,153,154,155,90,157,90,159,160,161,132,163,164,165,166,167,168,169,170,171,132,173,174,175,136,177,178,179,180,181,136,183,184,185,186,187,146,189,190,191,146,193,194,195,172,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,172,217,218,219,176,221,222,223,176,225,226,227,228,229,216,231,216,233,234,235,220,237,238,239,220,241,232,243,232,245,236,247,236,249] + "parent_index": [0,0,1,0,3,0,5,0,7,0,9,0,11,12,13,14,15,0,17,0,19,4,21,4,23,6,25,26,27,28,29,6,31,32,33,34,35,8,37,8,39,40,41,10,43,10,45,46,47,48,49,50,51,18,53,18,55,0,57,22,59,22,61,24,63,64,65,66,67,24,69,70,71,30,73,30,75,36,77,36,79,38,81,38,83,84,85,42,87,42,89,44,91,92,93,94,95,44,97,98,99,100,101,52,103,52,105,54,107,108,109,110,111,54,113,114,115,116,117,56,119,120,121,122,123,56,125,126,127,128,129,60,131,60,133,134,135,62,137,138,139,140,141,142,143,62,145,82,147,148,149,150,151,82,153,154,155,90,157,90,159,160,161,132,163,164,165,166,167,168,169,170,171,132,173,174,175,136,177,178,179,180,181,136,183,184,185,186,187,146,189,190,191,146,193,194,195,172,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,172,217,218,219,176,221,222,223,176,225,226,227,228,229,216,231,216,233,234,235,220,237,238,239,220,241,232,243,232,245,236,247,236,249] },{ "mechanisms": [{ "indexes": [1,19,57], @@ -1131,7 +1131,7 @@ "indexes": [1,3,5,7,9,11,12,13,14,15,17,19,21,23,25,26,27,28,29,31,32,33,34,35,37,39,40,41,43,45,46,47,48,49,50,51,53,55,57,59,61,63,64,65,66,67,69,70,71,73,75,77,79,81,83,84,85,87,89,91,92,93,94,95,97,98,99,100,101,103,105,107,108,109,110,111,113,114,115,116,117,119,120,121,122,123,125,126,127,128,129,131,133,134,135,137,138,139,140,141,142,143,145,147,148,149,150,151,153,154,155,157,159,160,161,163,164,165,166,167,168,169,170,171,173,174,175,177,178,179,180,181,183,184,185,186,187,189,190,191,193,194,195,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,217,218,219,221,222,223,225,226,227,228,229,231,233,234,235,237,238,239,241,243,245,247,249], "name": "pas" }], - "parent_index": [0,0,1,0,3,0,5,0,7,0,9,0,11,12,13,14,15,0,17,2,19,4,21,4,23,6,25,26,27,28,29,6,31,32,33,34,35,8,37,8,39,40,41,10,43,10,45,46,47,48,49,50,51,18,53,18,55,20,57,22,59,22,61,24,63,64,65,66,67,24,69,70,71,30,73,30,75,36,77,36,79,38,81,38,83,84,85,42,87,42,89,44,91,92,93,94,95,44,97,98,99,100,101,52,103,52,105,54,107,108,109,110,111,54,113,114,115,116,117,56,119,120,121,122,123,56,125,126,127,128,129,60,131,60,133,134,135,62,137,138,139,140,141,142,143,62,145,82,147,148,149,150,151,82,153,154,155,90,157,90,159,160,161,132,163,164,165,166,167,168,169,170,171,132,173,174,175,136,177,178,179,180,181,136,183,184,185,186,187,146,189,190,191,146,193,194,195,172,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,172,217,218,219,176,221,222,223,176,225,226,227,228,229,216,231,216,233,234,235,220,237,238,239,220,241,232,243,232,245,236,247,236,249] + "parent_index": [0,0,1,0,3,0,5,0,7,0,9,0,11,12,13,14,15,0,17,0,19,4,21,4,23,6,25,26,27,28,29,6,31,32,33,34,35,8,37,8,39,40,41,10,43,10,45,46,47,48,49,50,51,18,53,18,55,0,57,22,59,22,61,24,63,64,65,66,67,24,69,70,71,30,73,30,75,36,77,36,79,38,81,38,83,84,85,42,87,42,89,44,91,92,93,94,95,44,97,98,99,100,101,52,103,52,105,54,107,108,109,110,111,54,113,114,115,116,117,56,119,120,121,122,123,56,125,126,127,128,129,60,131,60,133,134,135,62,137,138,139,140,141,142,143,62,145,82,147,148,149,150,151,82,153,154,155,90,157,90,159,160,161,132,163,164,165,166,167,168,169,170,171,132,173,174,175,136,177,178,179,180,181,136,183,184,185,186,187,146,189,190,191,146,193,194,195,172,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,172,217,218,219,176,221,222,223,176,225,226,227,228,229,216,231,216,233,234,235,220,237,238,239,220,241,232,243,232,245,236,247,236,249] },{ "mechanisms": [{ "indexes": [1,19,57], @@ -1194,7 +1194,7 @@ "indexes": [1,3,5,7,9,11,12,13,14,15,17,19,21,23,25,26,27,28,29,31,32,33,34,35,37,39,40,41,43,45,46,47,48,49,50,51,53,55,57,59,61,63,64,65,66,67,69,70,71,73,75,77,79,81,83,84,85,87,89,91,92,93,94,95,97,98,99,100,101,103,105,107,108,109,110,111,113,114,115,116,117,119,120,121,122,123,125,126,127,128,129,131,133,134,135,137,138,139,140,141,142,143,145,147,148,149,150,151,153,154,155,157,159,160,161,163,164,165,166,167,168,169,170,171,173,174,175,177,178,179,180,181,183,184,185,186,187,189,190,191,193,194,195,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,217,218,219,221,222,223,225,226,227,228,229,231,233,234,235,237,238,239,241,243,245,247,249], "name": "pas" }], - "parent_index": [0,0,1,0,3,0,5,0,7,0,9,0,11,12,13,14,15,0,17,2,19,4,21,4,23,6,25,26,27,28,29,6,31,32,33,34,35,8,37,8,39,40,41,10,43,10,45,46,47,48,49,50,51,18,53,18,55,20,57,22,59,22,61,24,63,64,65,66,67,24,69,70,71,30,73,30,75,36,77,36,79,38,81,38,83,84,85,42,87,42,89,44,91,92,93,94,95,44,97,98,99,100,101,52,103,52,105,54,107,108,109,110,111,54,113,114,115,116,117,56,119,120,121,122,123,56,125,126,127,128,129,60,131,60,133,134,135,62,137,138,139,140,141,142,143,62,145,82,147,148,149,150,151,82,153,154,155,90,157,90,159,160,161,132,163,164,165,166,167,168,169,170,171,132,173,174,175,136,177,178,179,180,181,136,183,184,185,186,187,146,189,190,191,146,193,194,195,172,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,172,217,218,219,176,221,222,223,176,225,226,227,228,229,216,231,216,233,234,235,220,237,238,239,220,241,232,243,232,245,236,247,236,249] + "parent_index": [0,0,1,0,3,0,5,0,7,0,9,0,11,12,13,14,15,0,17,0,19,4,21,4,23,6,25,26,27,28,29,6,31,32,33,34,35,8,37,8,39,40,41,10,43,10,45,46,47,48,49,50,51,18,53,18,55,0,57,22,59,22,61,24,63,64,65,66,67,24,69,70,71,30,73,30,75,36,77,36,79,38,81,38,83,84,85,42,87,42,89,44,91,92,93,94,95,44,97,98,99,100,101,52,103,52,105,54,107,108,109,110,111,54,113,114,115,116,117,56,119,120,121,122,123,56,125,126,127,128,129,60,131,60,133,134,135,62,137,138,139,140,141,142,143,62,145,82,147,148,149,150,151,82,153,154,155,90,157,90,159,160,161,132,163,164,165,166,167,168,169,170,171,132,173,174,175,136,177,178,179,180,181,136,183,184,185,186,187,146,189,190,191,146,193,194,195,172,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,172,217,218,219,176,221,222,223,176,225,226,227,228,229,216,231,216,233,234,235,220,237,238,239,220,241,232,243,232,245,236,247,236,249] },{ "mechanisms": [{ "indexes": [1,19,57], @@ -1257,5 +1257,5 @@ "indexes": [1,3,5,7,9,11,12,13,14,15,17,19,21,23,25,26,27,28,29,31,32,33,34,35,37,39,40,41,43,45,46,47,48,49,50,51,53,55,57,59,61,63,64,65,66,67,69,70,71,73,75,77,79,81,83,84,85,87,89,91,92,93,94,95,97,98,99,100,101,103,105,107,108,109,110,111,113,114,115,116,117,119,120,121,122,123,125,126,127,128,129,131,133,134,135,137,138,139,140,141,142,143,145,147,148,149,150,151,153,154,155,157,159,160,161,163,164,165,166,167,168,169,170,171,173,174,175,177,178,179,180,181,183,184,185,186,187,189,190,191,193,194,195,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,217,218,219,221,222,223,225,226,227,228,229,231,233,234,235,237,238,239,241,243,245,247,249], "name": "pas" }], - "parent_index": [0,0,1,0,3,0,5,0,7,0,9,0,11,12,13,14,15,0,17,2,19,4,21,4,23,6,25,26,27,28,29,6,31,32,33,34,35,8,37,8,39,40,41,10,43,10,45,46,47,48,49,50,51,18,53,18,55,20,57,22,59,22,61,24,63,64,65,66,67,24,69,70,71,30,73,30,75,36,77,36,79,38,81,38,83,84,85,42,87,42,89,44,91,92,93,94,95,44,97,98,99,100,101,52,103,52,105,54,107,108,109,110,111,54,113,114,115,116,117,56,119,120,121,122,123,56,125,126,127,128,129,60,131,60,133,134,135,62,137,138,139,140,141,142,143,62,145,82,147,148,149,150,151,82,153,154,155,90,157,90,159,160,161,132,163,164,165,166,167,168,169,170,171,132,173,174,175,136,177,178,179,180,181,136,183,184,185,186,187,146,189,190,191,146,193,194,195,172,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,172,217,218,219,176,221,222,223,176,225,226,227,228,229,216,231,216,233,234,235,220,237,238,239,220,241,232,243,232,245,236,247,236,249] + "parent_index": [0,0,1,0,3,0,5,0,7,0,9,0,11,12,13,14,15,0,17,0,19,4,21,4,23,6,25,26,27,28,29,6,31,32,33,34,35,8,37,8,39,40,41,10,43,10,45,46,47,48,49,50,51,18,53,18,55,0,57,22,59,22,61,24,63,64,65,66,67,24,69,70,71,30,73,30,75,36,77,36,79,38,81,38,83,84,85,42,87,42,89,44,91,92,93,94,95,44,97,98,99,100,101,52,103,52,105,54,107,108,109,110,111,54,113,114,115,116,117,56,119,120,121,122,123,56,125,126,127,128,129,60,131,60,133,134,135,62,137,138,139,140,141,142,143,62,145,82,147,148,149,150,151,82,153,154,155,90,157,90,159,160,161,132,163,164,165,166,167,168,169,170,171,132,173,174,175,136,177,178,179,180,181,136,183,184,185,186,187,146,189,190,191,146,193,194,195,172,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,172,217,218,219,176,221,222,223,176,225,226,227,228,229,216,231,216,233,234,235,220,237,238,239,220,241,232,243,232,245,236,247,236,249] }] diff --git a/miniapp/io.cpp b/miniapp/io.cpp index 6664cf47e4ddbf1fcd33cd4589553a29cb967255..ac7573ccec32a4036f49c515b80047ccb602a1e0 100644 --- a/miniapp/io.cpp +++ b/miniapp/io.cpp @@ -1,13 +1,37 @@ -#include <fstream> #include <exception> +#include <fstream> +#include <istream> #include <tclap/CmdLine.h> #include <json/src/json.hpp> +#include <util/optional.hpp> + #include "io.hpp" +// Let TCLAP understand value arguments that are of an optional type. + +template <typename V> +struct TCLAP::ArgTraits<nest::mc::util::optional<V>> { + using ValueCategory = ValueLike; +}; + namespace nest { namespace mc { + +// Using static here because we do not want external linkage for this operator + +namespace util { + template <typename V> + static std::istream& operator>>(std::istream& I, optional<V>& v) { + V u; + if (I >> u) { + v = u; + } + return I; + } +} + namespace io { /// read simulation options from json file with name fname @@ -17,7 +41,8 @@ namespace io { cl_options read_options(int argc, char** argv) { // set default options - const cl_options defopts{"", 1000, 500, "expsyn", 100, 100., 0.025, false}; + const cl_options defopts{"", 1000, 500, "expsyn", 100, 100., 0.025, false, + false, 1.0, "trace_", util::nothing}; cl_options options; // parse command line arguments @@ -47,6 +72,17 @@ cl_options read_options(int argc, char** argv) { false, defopts.dt, "positive real number", cmd); TCLAP::SwitchArg all_to_all_arg( "m","alltoall","all to all network", cmd, false); + TCLAP::ValueArg<double> probe_ratio_arg( + "p", "probe-ratio", "proportion of cells to probe", + false, defopts.probe_ratio, "real number in [0,1]", cmd); + TCLAP::SwitchArg probe_soma_only_arg( + "X", "probe-soma-only", "only probe cell somas, not dendrites", cmd, false); + TCLAP::ValueArg<std::string> trace_prefix_arg( + "P", "trace-prefix", "write traces to files with this prefix", + false, defopts.trace_prefix, "stringr", cmd); + TCLAP::ValueArg<util::optional<unsigned>> trace_max_gid_arg( + "T", "trace-max-gid", "only trace probes on cells up to this gid", + false, defopts.trace_max_gid, "unisgned integer", cmd); cmd.parse(argc, argv); @@ -58,6 +94,10 @@ cl_options read_options(int argc, char** argv) { options.tfinal = tfinal_arg.getValue(); options.dt = dt_arg.getValue(); options.all_to_all = all_to_all_arg.getValue(); + options.probe_ratio = probe_ratio_arg.getValue(); + options.probe_soma_only = probe_soma_only_arg.getValue(); + options.trace_prefix = trace_prefix_arg.getValue(); + options.trace_max_gid = trace_max_gid_arg.getValue(); } // catch any exceptions in command line handling catch (TCLAP::ArgException& e) { @@ -100,6 +140,14 @@ std::ostream& operator<<(std::ostream& o, const cl_options& options) { o << " simulation time : " << options.tfinal << "\n"; o << " dt : " << options.dt << "\n"; o << " all to all network : " << (options.all_to_all ? "yes" : "no") << "\n"; + o << " probe ratio : " << options.probe_ratio << "\n"; + o << " probe soma only : " << (options.probe_soma_only ? "yes" : "no") << "\n"; + o << " trace prefix : " << options.trace_prefix << "\n"; + o << " trace max gid : "; + if (options.trace_max_gid) { + o << *options.trace_max_gid; + } + o << "\n"; o << " input file name : " << options.ifname << "\n"; return o; diff --git a/miniapp/io.hpp b/miniapp/io.hpp index dab584fe2a132f289bb9a2f1ae02711aa29ef5a4..71af61810670d7a1f226d3eec2dabfd2f38ff20e 100644 --- a/miniapp/io.hpp +++ b/miniapp/io.hpp @@ -6,6 +6,8 @@ #include <stdexcept> #include <utility> +#include <util/optional.hpp> + namespace nest { namespace mc { namespace io { @@ -20,6 +22,10 @@ struct cl_options { double tfinal; double dt; bool all_to_all; + bool probe_soma_only; + double probe_ratio; + std::string trace_prefix; + util::optional<unsigned> trace_max_gid; }; class usage_error: public std::runtime_error { diff --git a/miniapp/miniapp.cpp b/miniapp/miniapp.cpp index 9b26ff86ef37f829667161afca27a129791de3ed..3e9d4dd227efbb90823b99db2fedd00cc94e4f81 100644 --- a/miniapp/miniapp.cpp +++ b/miniapp/miniapp.cpp @@ -32,7 +32,7 @@ using model_type = model<lowered_cell>; using sample_trace_type = sample_trace<model_type::time_type, model_type::value_type>; void banner(); -std::unique_ptr<recipe> make_recipe(const io::cl_options&); +std::unique_ptr<recipe> make_recipe(const io::cl_options&, const probe_distribution&); std::unique_ptr<sample_trace_type> make_trace(cell_member_type probe_id, probe_spec probe); std::pair<cell_gid_type, cell_gid_type> distribute_cells(cell_size_type ncells); @@ -53,7 +53,12 @@ int main(int argc, char** argv) { << std::ceil(options.tfinal / options.dt) << " steps of " << options.dt << " ms" << std::endl; - auto recipe = make_recipe(options); + // determine what to attach probes to + probe_distribution pdist; + pdist.proportion = options.probe_ratio; + pdist.all_segments = !options.probe_soma_only; + + auto recipe = make_recipe(options, pdist); auto cell_range = distribute_cells(recipe->num_cells()); // build model from recipe @@ -69,6 +74,10 @@ int main(int argc, char** argv) { std::vector<std::unique_ptr<sample_trace_type>> traces; const model_type::time_type sample_dt = 0.1; for (auto probe: m.probes()) { + if (options.trace_max_gid && probe.id.gid>*options.trace_max_gid) { + continue; + } + traces.push_back(make_trace(probe.id, probe.probe)); m.attach_sampler(probe.id, make_trace_sampler(traces.back().get(),sample_dt)); } @@ -81,7 +90,7 @@ int main(int argc, char** argv) { // save traces for (const auto& trace: traces) { - write_trace_json(*trace.get()); + write_trace_json(*trace.get(), options.trace_prefix); } } catch (io::usage_error& e) { @@ -119,7 +128,7 @@ void banner() { std::cout << "====================\n"; } -std::unique_ptr<recipe> make_recipe(const io::cl_options& options) { +std::unique_ptr<recipe> make_recipe(const io::cl_options& options, const probe_distribution& pdist) { basic_recipe_param p; p.num_compartments = options.compartments_per_segment; @@ -127,17 +136,17 @@ std::unique_ptr<recipe> make_recipe(const io::cl_options& options) { p.synapse_type = options.syn_type; if (options.all_to_all) { - return make_basic_kgraph_recipe(options.cells, p); + return make_basic_kgraph_recipe(options.cells, p, pdist); } else { - return make_basic_rgraph_recipe(options.cells, p); + return make_basic_rgraph_recipe(options.cells, p, pdist); } } std::unique_ptr<sample_trace_type> make_trace(cell_member_type probe_id, probe_spec probe) { std::string name = ""; std::string units = ""; - + switch (probe.kind) { case probeKind::membrane_voltage: name = "v"; diff --git a/miniapp/miniapp_recipes.cpp b/miniapp/miniapp_recipes.cpp index 22c59bd851a049e448784b9cfdd635d7e7a96970..742951dff6df83cb13c2f13af6e2d1ace2ae97eb 100644 --- a/miniapp/miniapp_recipes.cpp +++ b/miniapp/miniapp_recipes.cpp @@ -76,13 +76,15 @@ public: EXPECTS(cell.detectors().size()==cc.num_sources); // add probes - unsigned n_probe_segs = pdist_.all_segments? basic_cell_segments: 1u; - for (unsigned i = 0; i<n_probe_segs; ++i) { - if (pdist_.membrane_voltage) { - cell.add_probe({{i, i? 0.5: 0.0}, mc::probeKind::membrane_voltage}); - } - if (pdist_.membrane_current) { - cell.add_probe({{i, i? 0.5: 0.0}, mc::probeKind::membrane_current}); + if (cc.num_probes) { + unsigned n_probe_segs = pdist_.all_segments? basic_cell_segments: 1u; + for (unsigned i = 0; i<n_probe_segs; ++i) { + if (pdist_.membrane_voltage) { + cell.add_probe({{i, i? 0.5: 0.0}, mc::probeKind::membrane_voltage}); + } + if (pdist_.membrane_current) { + cell.add_probe({{i, i? 0.5: 0.0}, mc::probeKind::membrane_current}); + } } } EXPECTS(cell.probes().size()==cc.num_probes); diff --git a/src/algorithms.hpp b/src/algorithms.hpp index 7789b24156d403ba702404ccf67a67d0b2cfcedf..5456417ddaea0e0fe6c4e777a0fa8ebf3344c2ed 100644 --- a/src/algorithms.hpp +++ b/src/algorithms.hpp @@ -121,49 +121,42 @@ bool is_positive(C const& c) } template<typename C> -bool has_contiguous_segments(const C& parent_index) +std::vector<typename C::value_type> child_count(const C& parent_index) { static_assert( std::is_integral<typename C::value_type>::value, "integral type required" ); - if (!is_minimal_degree(parent_index)) { - return false; - } - - int n = parent_index.size(); - std::vector<bool> is_leaf(n, false); - - for(auto i=1; i<n; ++i) { - auto p = parent_index[i]; - if(is_leaf[p]) { - return false; - } - - if(p != decltype(p)(i-1)) { - // we have a branch and i-1 is a leaf node - is_leaf[i-1] = true; - } + std::vector<typename C::value_type> count(parent_index.size(), 0); + for (auto i = 1u; i < parent_index.size(); ++i) { + ++count[parent_index[i]]; } - return true; + return count; } template<typename C> -std::vector<typename C::value_type> child_count(const C& parent_index) +bool has_contiguous_compartments(const C& parent_index) { static_assert( std::is_integral<typename C::value_type>::value, "integral type required" ); - std::vector<typename C::value_type> count(parent_index.size(), 0); - for (std::size_t i = 1; i < parent_index.size(); ++i) { - ++count[parent_index[i]]; + if (!is_minimal_degree(parent_index)) { + return false; } - return count; + auto num_child = child_count(parent_index); + for (auto i = 1u; i < parent_index.size(); ++i) { + auto p = parent_index[i]; + if (num_child[p] == 1 && p != i-1) { + return false; + } + } + + return true; } template<typename C> @@ -174,7 +167,7 @@ std::vector<typename C::value_type> branches(const C& parent_index) "integral type required" ); - //EXPECTS(has_contiguous_segments(parent_index)); + EXPECTS(has_contiguous_compartments(parent_index)); std::vector<typename C::value_type> branch_index; if (parent_index.empty()) { @@ -249,8 +242,8 @@ std::vector<typename C::value_type> make_parent_index( return {}; } - EXPECTS(parent_index.size() == unsigned(branch_index.back())); - //EXPECTS(has_contiguous_segments(parent_index)); + EXPECTS(parent_index.size() == branch_index.back()); + EXPECTS(has_contiguous_compartments(parent_index)); EXPECTS(is_strictly_monotonic_increasing(branch_index)); // expand the branch index diff --git a/src/communication/communicator.hpp b/src/communication/communicator.hpp index 871bf65266da7c7ffcc962a41f9913d93fa89fc2..8c72430f5c4646ce7747c76cac088bee65a58df8 100644 --- a/src/communication/communicator.hpp +++ b/src/communication/communicator.hpp @@ -5,11 +5,12 @@ #include <vector> #include <random> +#include <spike.hpp> +#include <util/double_buffer.hpp> #include <algorithms.hpp> #include <connection.hpp> #include <event_queue.hpp> #include <spike.hpp> -#include <threading/threading.hpp> #include <util/debug.hpp> namespace nest { @@ -29,43 +30,50 @@ namespace communication { template <typename Time, typename CommunicationPolicy> class communicator { public: + using communication_policy_type = CommunicationPolicy; using id_type = cell_gid_type; using time_type = Time; - using communication_policy_type = CommunicationPolicy; - using spike_type = spike<cell_member_type, time_type>; + using connection_type = connection<time_type>; + + /// per-cell group lists of events to be delivered + using event_queue = + std::vector<postsynaptic_spike_event<time_type>>; communicator() = default; + // TODO // for now, still assuming one-to-one association cells <-> groups, // so that 'group' gids as represented by their first cell gid are // contiguous. communicator(id_type cell_from, id_type cell_to): cell_gid_from_(cell_from), cell_gid_to_(cell_to) - { - auto num_groups_local_ = cell_gid_to_-cell_gid_from_; + {} - // create an event queue for each target group - events_.resize(num_groups_local_); + cell_local_size_type num_groups_local() const + { + return cell_gid_to_-cell_gid_from_; } - - void add_connection(connection<time_type> con) { + void add_connection(connection_type con) { EXPECTS(is_local_cell(con.destination().gid)); connections_.push_back(con); } + /// returns true if the cell with gid is on the domain of the caller bool is_local_cell(id_type gid) const { return gid>=cell_gid_from_ && gid<cell_gid_to_; } - // builds the optimized data structure + /// builds the optimized data structure + /// must be called after all connections have been added void construct() { if (!std::is_sorted(connections_.begin(), connections_.end())) { std::sort(connections_.begin(), connections_.end()); } } + /// the minimum delay of all connections in the global network. time_type min_delay() { auto local_min = std::numeric_limits<time_type>::max(); for (auto& con : connections_) { @@ -75,31 +83,22 @@ public: return communication_policy_.min(local_min); } - void add_spike(spike_type s) { - thread_spikes().push_back(s); - } - - void add_spikes(const std::vector<spike_type>& s) { - auto& v = thread_spikes(); - v.insert(v.end(), s.begin(), s.end()); - } - - std::vector<spike_type>& thread_spikes() { - return thread_spikes_.local(); - } - - void exchange() { - // global all-to-all to gather a local copy of the global spike list - // on each node - auto global_spikes = communication_policy_.gather_spikes(local_spikes()); + /// Perform exchange of spikes. + /// + /// Takes as input the list of local_spikes that were generated on the calling domain. + /// + /// Returns a vector of event queues, with one queue for each local cell group. The + /// events in each queue are all events that must be delivered to targets in that cell + /// group as a result of the global spike exchange. + std::vector<event_queue> exchange(const std::vector<spike_type>& local_spikes) { + // global all-to-all to gather a local copy of the global spike list on each node. + auto global_spikes = communication_policy_.gather_spikes( local_spikes ); num_spikes_ += global_spikes.size(); - clear_thread_spike_buffers(); - for (auto& q : events_) { - q.clear(); - } + // check each global spike in turn to see it generates local events. + // if so, make the events and insert them into the appropriate event list. + auto queues = std::vector<event_queue>(num_groups_local()); - // check all global spikes to see if they will generate local events for (auto spike : global_spikes) { // search for targets auto targets = @@ -110,18 +109,18 @@ public: // generate an event for each target for (auto it=targets.first; it!=targets.second; ++it) { auto gidx = cell_group_index(it->destination().gid); - events_[gidx].push_back(it->make_event(spike)); + queues[gidx].push_back(it->make_event(spike)); } } + + return queues; } + /// Returns the total number of global spikes over the duration + /// of the simulation uint64_t num_spikes() const { return num_spikes_; } - const std::vector<postsynaptic_spike_event<time_type>>& queue(int i) const { - return events_[i]; - } - - const std::vector<connection<time_type>>& connections() const { + const std::vector<connection_type>& connections() const { return connections_; } @@ -129,28 +128,6 @@ public: return communication_policy_; } - std::vector<spike_type> local_spikes() { - std::vector<spike_type> spikes; - for (auto& v : thread_spikes_) { - spikes.insert(spikes.end(), v.begin(), v.end()); - } - return spikes; - } - - void clear_thread_spike_buffers() { - for (auto& v : thread_spikes_) { - v.clear(); - } - } - - void reset() { - // remove all in-flight spikes/events - clear_thread_spike_buffers(); - for (auto& evbuf: events_) { - evbuf.clear(); - } - } - private: std::size_t cell_group_index(cell_gid_type cell_gid) const { // this will be more elaborate when there is more than one cell per cell group @@ -158,24 +135,7 @@ private: return cell_gid-cell_gid_from_; } - // - // both of these can be fixed with double buffering - // - // FIXME : race condition on the thread_spikes_ buffers when exchange() modifies/access them - // ... other threads will be pushing to them simultaneously - // FIXME : race condition on the group-specific event queues when exchange pushes to them - // ... other threads will be accessing them to update their event queues - - // thread private storage for accumulating spikes - using local_spike_store_type = - nest::mc::threading::enumerable_thread_specific<std::vector<spike_type>>; - local_spike_store_type thread_spikes_; - - std::vector<connection<time_type>> connections_; - std::vector<std::vector<postsynaptic_spike_event<time_type>>> events_; - - // for keeping track of how time is spent where - //util::Profiler profiler_; + std::vector<connection_type> connections_; communication_policy_type communication_policy_; diff --git a/src/model.hpp b/src/model.hpp index 3812a44bfffaa21397d12953c93fcd13bb3843d9..84dd84298a78418ce882b68a29f2211a6e50401b 100644 --- a/src/model.hpp +++ b/src/model.hpp @@ -6,10 +6,11 @@ #include <common_types.hpp> #include <cell.hpp> #include <cell_group.hpp> -#include <communication/communicator.hpp> -#include <communication/global_policy.hpp> #include <fvm_cell.hpp> #include <recipe.hpp> +#include <thread_private_spike_store.hpp> +#include <communication/communicator.hpp> +#include <communication/global_policy.hpp> #include <profiling/profiler.hpp> #include "trace_sampler.hpp" @@ -36,9 +37,10 @@ public: cell_to_(cell_to), communicator_(cell_from, cell_to) { + // generate the cell groups in parallel, with one task per cell group cell_groups_ = std::vector<cell_group_type>{cell_to_-cell_from_}; - threading::parallel_vector<probe_record> probes; + threading::parallel_for::apply(cell_from_, cell_to_, [&](cell_gid_type i) { PE("setup", "cells"); @@ -54,8 +56,10 @@ public: PL(2); }); + // insert probes probes_.assign(probes.begin(), probes.end()); + // generate the network connections for (cell_gid_type i=cell_from_; i<cell_to_; ++i) { for (const auto& cc: rec.connections_on(i)) { connection<time_type> conn{cc.source, cc.dest, cc.weight, cc.delay}; @@ -63,6 +67,12 @@ public: } } communicator_.construct(); + + // Allocate an empty queue buffer for each cell group + // These must be set initially to ensure that a queue is available for each + // cell group for the first time step. + current_events().resize(num_groups()); + future_events().resize(num_groups()); } void reset() { @@ -74,41 +84,74 @@ public: } time_type run(time_type tfinal, time_type dt) { - time_type min_delay = communicator_.min_delay(); - while (t_<tfinal) { - auto tuntil = std::min(t_+min_delay, tfinal); - threading::parallel_for::apply( - 0u, cell_groups_.size(), - [&](unsigned i) { - auto& group = cell_groups_[i]; - - PE("stepping","events"); - group.enqueue_events(communicator_.queue(i)); - PL(); + // Calculate the size of the largest possible time integration interval + // before communication of spikes is required. + // If spike exchange and cell update are serialized, this is the + // minimum delay of the network, however we use half this period + // to overlap communication and computation. + time_type t_interval = communicator_.min_delay()/2; - group.advance(tuntil, dt); - - PE("events"); - communicator_.add_spikes(group.spikes()); - group.clear_spikes(); - PL(2); - }); + while (t_<tfinal) { + auto tuntil = std::min(t_+t_interval, tfinal); + + event_queues_.exchange(); + local_spikes_.exchange(); + + // empty the spike buffers for the current integration period. + // these buffers will store the new spikes generated in update_cells. + current_spikes().clear(); + + // task that updates cell state in parallel. + auto update_cells = [&] () { + threading::parallel_for::apply( + 0u, cell_groups_.size(), + [&](unsigned i) { + auto &group = cell_groups_[i]; + + PE("stepping","events"); + group.enqueue_events(current_events()[i]); + PL(); + + group.advance(tuntil, dt); + + PE("events"); + current_spikes().insert(group.spikes()); + group.clear_spikes(); + PL(2); + }); + }; + + // task that performs spike exchange with the spikes generated in + // the previous integration period, generating the postsynaptic + // events that must be delivered at the start of the next + // integration period at the latest. + auto exchange = [&] () { + PE("stepping", "exchange"); + auto local_spikes = previous_spikes().gather(); + future_events() = communicator_.exchange(local_spikes); + PL(2); + }; - PE("stepping", "exchange"); - communicator_.exchange(); - PL(2); + // run the tasks, overlapping if the threading model and number of + // available threads permits it. + threading::task_group g; + g.run(exchange); + g.run(update_cells); + g.wait(); t_ = tuntil; } return t_; } + // only thread safe if called outside the run() method void add_artificial_spike(cell_member_type source) { add_artificial_spike(source, t_); } + // only thread safe if called outside the run() method void add_artificial_spike(cell_member_type source, time_type tspike) { - communicator_.add_spike({source, tspike}); + current_spikes().get().push_back({source, tspike}); } void attach_sampler(cell_member_type probe_id, sampler_function f, time_type tfrom = 0) { @@ -122,6 +165,7 @@ public: const std::vector<probe_record>& probes() const { return probes_; } std::size_t num_spikes() const { return communicator_.num_spikes(); } + std::size_t num_groups() const { return cell_groups_.size(); } private: cell_gid_type cell_from_; @@ -130,6 +174,35 @@ private: std::vector<cell_group_type> cell_groups_; communicator_type communicator_; std::vector<probe_record> probes_; + using spike_type = typename communicator_type::spike_type; + + using event_queue_type = typename communicator_type::event_queue; + util::double_buffer< std::vector<event_queue_type> > event_queues_; + + using local_spike_store_type = thread_private_spike_store<time_type>; + util::double_buffer< local_spike_store_type > local_spikes_; + + // Convenience functions that map the spike buffers and event queues onto + // the appropriate integration interval. + // + // To overlap communication and computation, integration intervals of + // size Delta/2 are used, where Delta is the minimum delay in the global + // system. + // From the frame of reference of the current integration period we + // define three intervals: previous, current and future + // Then we define the following : + // current_spikes : spikes generated in the current interval + // previous_spikes: spikes generated in the preceding interval + // current_events : events to be delivered at the start of + // the current interval + // future_events : events to be delivered at the start of + // the next interval + + local_spike_store_type& current_spikes() { return local_spikes_.get(); } + local_spike_store_type& previous_spikes() { return local_spikes_.other(); } + + std::vector<event_queue_type>& current_events() { return event_queues_.get(); } + std::vector<event_queue_type>& future_events() { return event_queues_.other(); } }; } // namespace mc diff --git a/src/swcio.cpp b/src/swcio.cpp index 3f38f8e791308819ac2fe3eeecde4c78ab585799..db8001be40447864ce5c6c5974f274fb516afcf8 100644 --- a/src/swcio.cpp +++ b/src/swcio.cpp @@ -261,7 +261,7 @@ swc_record_range_clean::swc_record_range_clean(std::istream& is) parent_list.push_back(records_[i].parent()); } - if (!nest::mc::algorithms::has_contiguous_segments(parent_list)) { + if (!nest::mc::algorithms::has_contiguous_compartments(parent_list)) { throw swc_parse_error("branches are not contiguously numbered", 0); } } diff --git a/src/thread_private_spike_store.hpp b/src/thread_private_spike_store.hpp new file mode 100644 index 0000000000000000000000000000000000000000..1e14ab104619a42b8aa9f014172bb5716576017c --- /dev/null +++ b/src/thread_private_spike_store.hpp @@ -0,0 +1,75 @@ +#pragma once + +#include <vector> + +#include <common_types.hpp> +#include <spike.hpp> +#include <threading/threading.hpp> + +namespace nest { +namespace mc { + +/// Handles the complexity of managing thread private buffers of spikes. +/// Internally stores one thread private buffer of spikes for each hardware thread. +/// This can be accessed directly using the get() method, which returns a reference to +/// The thread private buffer of the calling thread. +/// The insert() and gather() methods add a vector of spikes to the buffer, +/// and collate all of the buffers into a single vector respectively. +template <typename Time> +class thread_private_spike_store { +public : + using id_type = cell_gid_type; + using time_type = Time; + using spike_type = spike<cell_member_type, time_type>; + + /// Collate all of the individual buffers into a single vector of spikes. + /// Does not modify the buffer contents. + std::vector<spike_type> gather() const { + std::vector<spike_type> spikes; + unsigned num_spikes = 0u; + for (auto& b : buffers_) { + num_spikes += b.size(); + } + spikes.reserve(num_spikes); + + for (auto& b : buffers_) { + spikes.insert(spikes.begin(), b.begin(), b.end()); + } + + return spikes; + } + + /// Return a reference to the thread private buffer of the calling thread + std::vector<spike_type>& get() { + return buffers_.local(); + } + + /// Return a reference to the thread private buffer of the calling thread + const std::vector<spike_type>& get() const { + return buffers_.local(); + } + + /// Clear all of the thread private buffers + void clear() { + for (auto& b : buffers_) { + b.clear(); + } + } + + /// Append the passed spikes to the end of the thread private buffer of the + /// calling thread + void insert(const std::vector<spike_type>& spikes) { + auto& buff = get(); + buff.insert(buff.end(), spikes.begin(), spikes.end()); + } + +private : + /// thread private storage for accumulating spikes + using local_spike_store_type = + threading::enumerable_thread_specific<std::vector<spike_type>>; + + local_spike_store_type buffers_; +}; + +} // namespace mc +} // namespace nest diff --git a/src/threading/serial.hpp b/src/threading/serial.hpp index 8d9c4d64fd84805ed0909ad704ffc192bd0da748..c18d4800e3c457e140f0fe6d2ca671aa6ccac241 100644 --- a/src/threading/serial.hpp +++ b/src/threading/serial.hpp @@ -19,6 +19,8 @@ namespace threading { template <typename T> class enumerable_thread_specific { std::array<T, 1> data; + using iterator_type = typename std::array<T, 1>::iterator; + using const_iterator_type = typename std::array<T, 1>::const_iterator; public : @@ -37,11 +39,14 @@ class enumerable_thread_specific { auto size() -> decltype(data.size()) const { return data.size(); } - auto begin() -> decltype(data.begin()) { return data.begin(); } - auto end() -> decltype(data.end()) { return data.end(); } + iterator_type begin() { return data.begin(); } + iterator_type end() { return data.end(); } - auto cbegin() -> decltype(data.cbegin()) const { return data.cbegin(); } - auto cend() -> decltype(data.cend()) const { return data.cend(); } + const_iterator_type begin() const { return data.begin(); } + const_iterator_type end() const { return data.end(); } + + const_iterator_type cbegin() const { return data.cbegin(); } + const_iterator_type cend() const { return data.cend(); } }; @@ -83,6 +88,34 @@ struct timer { constexpr bool multithreaded() { return false; } +/// Proxy for tbb task group. +/// The tbb version launches tasks asynchronously, returning control to the +/// caller. The serial version implemented here simply runs the task, before +/// returning control, effectively serializing all asynchronous calls. +class task_group { +public: + task_group() = default; + + template<typename Func> + void run(const Func& f) { + f(); + } + + template<typename Func> + void run_and_wait(const Func& f) { + f(); + } + + void wait() + {} + + bool is_canceling() { + return false; + } + + void cancel() + {} +}; } // threading } // mc diff --git a/src/threading/tbb.hpp b/src/threading/tbb.hpp index 8e0086741cac1d51e02e9fa148e9eaa3f3f837a3..853ceefde731cb1cd4db323541132c935011c73a 100644 --- a/src/threading/tbb.hpp +++ b/src/threading/tbb.hpp @@ -49,6 +49,8 @@ constexpr bool multithreaded() { return true; } template <typename T> using parallel_vector = tbb::concurrent_vector<T>; +using task_group = tbb::task_group; + } // threading } // mc } // nest diff --git a/src/util/double_buffer.hpp b/src/util/double_buffer.hpp new file mode 100644 index 0000000000000000000000000000000000000000..31cffa1babef2ced0b843b4d3e375678612528b2 --- /dev/null +++ b/src/util/double_buffer.hpp @@ -0,0 +1,66 @@ +#pragma once + +#include <array> +#include <atomic> + +#include <util/debug.hpp> + +namespace nest { +namespace mc { +namespace util { + +/// double buffer with thread safe exchange/flip operation. +template <typename T> +class double_buffer { +private: + std::atomic<int> index_; + std::array<T, 2> buffers_; + + int other_index() { + return index_ ? 0 : 1; + } + +public: + using value_type = T; + + double_buffer() : + index_(0) + {} + + /// remove the copy and move constructors which won't work with std::atomic + double_buffer(double_buffer&&) = delete; + double_buffer(const double_buffer&) = delete; + double_buffer& operator=(const double_buffer&) = delete; + double_buffer& operator=(double_buffer&&) = delete; + + /// flip the buffers in a thread safe manner + /// n calls to exchange will always result in n flips + void exchange() { + // use operator^= which is overloaded by std::atomic<> + index_ ^= 1; + } + + /// get the current/front buffer + value_type& get() { + return buffers_[index_]; + } + + /// get the current/front buffer + const value_type& get() const { + return buffers_[index_]; + } + + /// get the back buffer + value_type& other() { + return buffers_[other_index()]; + } + + /// get the back buffer + const value_type& other() const { + return buffers_[other_index()]; + } +}; + +} // namespace util +} // namespace mc +} // namespace nest diff --git a/tests/unit/CMakeLists.txt b/tests/unit/CMakeLists.txt index 4ba5bb8b0be6764e84fb24ea1c16ee803f6bc516..fb1b9369d4e38498c8953fc0ce2f16c1dbc715dc 100644 --- a/tests/unit/CMakeLists.txt +++ b/tests/unit/CMakeLists.txt @@ -11,6 +11,7 @@ set(HEADERS set(TEST_SOURCES # unit tests test_algorithms.cpp + test_double_buffer.cpp test_cell.cpp test_compartments.cpp test_event_queue.cpp @@ -26,6 +27,7 @@ set(TEST_SOURCES test_probe.cpp test_segment.cpp test_spikes.cpp + test_spike_store.cpp test_stimulus.cpp test_swcio.cpp test_synapses.cpp @@ -45,12 +47,12 @@ foreach(target ${TARGETS}) target_link_libraries(${target} LINK_PUBLIC cellalgo gtest) if(WITH_TBB) - target_link_libraries(${target} LINK_PUBLIC ${TBB_LIBRARIES}) + target_link_libraries(${target} LINK_PUBLIC ${TBB_LIBRARIES}) endif() if(WITH_MPI) - target_link_libraries(${target} LINK_PUBLIC ${MPI_C_LIBRARIES}) - set_property(TARGET ${target} APPEND_STRING PROPERTY LINK_FLAGS "${MPI_C_LINK_FLAGS}") + target_link_libraries(${target} LINK_PUBLIC ${MPI_C_LIBRARIES}) + set_property(TARGET ${target} APPEND_STRING PROPERTY LINK_FLAGS "${MPI_C_LINK_FLAGS}") endif() set_target_properties(${target} diff --git a/tests/unit/test_algorithms.cpp b/tests/unit/test_algorithms.cpp index badaabffb605986578cbc15b9ed40b597a0e95ff..ebe19c3752e9e4eacb23008e467bca9a1fd95f79 100644 --- a/tests/unit/test_algorithms.cpp +++ b/tests/unit/test_algorithms.cpp @@ -172,7 +172,7 @@ TEST(algorithms, is_positive) ); } -TEST(algorithms, has_contiguous_segments) +TEST(algorithms, has_contiguous_compartments) { // // 0 @@ -186,7 +186,7 @@ TEST(algorithms, has_contiguous_segments) // 5 6 // EXPECT_FALSE( - nest::mc::algorithms::has_contiguous_segments( + nest::mc::algorithms::has_contiguous_compartments( std::vector<int>{0, 0, 1, 2, 2, 3, 4, 2} ) ); @@ -203,7 +203,7 @@ TEST(algorithms, has_contiguous_segments) // 4 7 // EXPECT_FALSE( - nest::mc::algorithms::has_contiguous_segments( + nest::mc::algorithms::has_contiguous_compartments( std::vector<int>{0, 0, 1, 2, 3, 2, 2, 5} ) ); @@ -220,7 +220,7 @@ TEST(algorithms, has_contiguous_segments) // 4 6 // EXPECT_TRUE( - nest::mc::algorithms::has_contiguous_segments( + nest::mc::algorithms::has_contiguous_compartments( std::vector<int>{0, 0, 1, 2, 3, 2, 5, 2} ) ); @@ -237,21 +237,34 @@ TEST(algorithms, has_contiguous_segments) // 4 6 // EXPECT_TRUE( - nest::mc::algorithms::has_contiguous_segments( + nest::mc::algorithms::has_contiguous_compartments( std::vector<int>{0, 0, 1, 2, 3, 2, 5, 1} ) ); + // + // 0 + // / \ + // 1 2 + // / \ + // 3 4 + // + EXPECT_TRUE( + nest::mc::algorithms::has_contiguous_compartments( + std::vector<int>{0, 0, 0, 1, 1} + ) + ); + // Soma-only list EXPECT_TRUE( - nest::mc::algorithms::has_contiguous_segments( + nest::mc::algorithms::has_contiguous_compartments( std::vector<int>{0} ) ); // Empty list EXPECT_TRUE( - nest::mc::algorithms::has_contiguous_segments( + nest::mc::algorithms::has_contiguous_compartments( std::vector<int>{} ) ); diff --git a/tests/unit/test_double_buffer.cpp b/tests/unit/test_double_buffer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1689cc2faac17331694c78830c22cd1ea57777fe --- /dev/null +++ b/tests/unit/test_double_buffer.cpp @@ -0,0 +1,58 @@ +#include "gtest.h" + +#include <util/double_buffer.hpp> + +// not much to test here: just test that values passed into the constructor +// are correctly stored in members +TEST(double_buffer, exchange_and_get) +{ + using namespace nest::mc::util; + + double_buffer<int> buf; + + buf.get() = 2134; + buf.exchange(); + buf.get() = 8990; + buf.exchange(); + + EXPECT_EQ(buf.get(), 2134); + EXPECT_EQ(buf.other(), 8990); + buf.exchange(); + EXPECT_EQ(buf.get(), 8990); + EXPECT_EQ(buf.other(), 2134); + buf.exchange(); + EXPECT_EQ(buf.get(), 2134); + EXPECT_EQ(buf.other(), 8990); +} + +TEST(double_buffer, assign_get_other) +{ + using namespace nest::mc::util; + + double_buffer<std::string> buf; + + buf.get() = "1"; + buf.other() = "2"; + + EXPECT_EQ(buf.get(), "1"); + EXPECT_EQ(buf.other(), "2"); +} + +TEST(double_buffer, non_pod) +{ + using namespace nest::mc::util; + + double_buffer<std::string> buf; + + buf.get() = "1"; + buf.other() = "2"; + + EXPECT_EQ(buf.get(), "1"); + EXPECT_EQ(buf.other(), "2"); + buf.exchange(); + EXPECT_EQ(buf.get(), "2"); + EXPECT_EQ(buf.other(), "1"); + buf.exchange(); + EXPECT_EQ(buf.get(), "1"); + EXPECT_EQ(buf.other(), "2"); +} diff --git a/tests/unit/test_spike_store.cpp b/tests/unit/test_spike_store.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dd075f878bfccc7a7a07887e6736fcb2768e0237 --- /dev/null +++ b/tests/unit/test_spike_store.cpp @@ -0,0 +1,84 @@ +#include "gtest.h" + +#include <thread_private_spike_store.hpp> + +TEST(spike_store, insert) +{ + using store_type = nest::mc::thread_private_spike_store<float>; + + store_type store; + + // insert 3 spike events and check that they were inserted correctly + store.insert({ + {{0,0}, 0.0f}, + {{1,2}, 0.5f}, + {{2,4}, 1.0f} + }); + + { + EXPECT_EQ(store.get().size(), 3u); + auto i = 0u; + for (auto& spike : store.get()) { + EXPECT_EQ(spike.source.gid, i); + EXPECT_EQ(spike.source.index, 2*i); + EXPECT_EQ(spike.time, float(i)/2.f); + ++i; + } + } + + // insert another 3 events, then check that they were appended to the + // original three events correctly + store.insert({ + {{3,6}, 1.5f}, + {{4,8}, 2.0f}, + {{5,10}, 2.5f} + }); + + { + EXPECT_EQ(store.get().size(), 6u); + auto i = 0u; + for (auto& spike : store.get()) { + EXPECT_EQ(spike.source.gid, i); + EXPECT_EQ(spike.source.index, 2*i); + EXPECT_EQ(spike.time, float(i)/2.f); + ++i; + } + } +} + +TEST(spike_store, clear) +{ + using store_type = nest::mc::thread_private_spike_store<float>; + + store_type store; + + // insert 3 spike events + store.insert({ + {{0,0}, 0.0f}, {{1,2}, 0.5f}, {{2,4}, 1.0f} + }); + EXPECT_EQ(store.get().size(), 3u); + store.clear(); + EXPECT_EQ(store.get().size(), 0u); +} + +TEST(spike_store, gather) +{ + using store_type = nest::mc::thread_private_spike_store<float>; + + store_type store; + + auto spikes = std::vector<store_type::spike_type> + { {{0,0}, 0.0f}, {{1,2}, 0.5f}, {{2,4}, 1.0f} }; + + store.insert(spikes); + auto gathered_spikes = store.gather(); + + EXPECT_EQ(gathered_spikes.size(), spikes.size()); + + for(auto i=0u; i<spikes.size(); ++i) { + EXPECT_EQ(spikes[i].source.gid, gathered_spikes[i].source.gid); + EXPECT_EQ(spikes[i].source.index, gathered_spikes[i].source.index); + EXPECT_EQ(spikes[i].time, gathered_spikes[i].time); + } +} +