| 1876 | } |
| 1877 | |
| 1878 | void ExtractConcatParameters(const caffe::LayerParameter& src, XGraph& graph) |
| 1879 | { |
| 1880 | // Map the Caffe layer type to anonymoX layer type |
| 1881 | caffe::ConcatParameter src_parameter = src.concat_param(); |
| 1882 | mapStrStr::const_iterator it_type = CaffeLayerMap.find(src.type()); |
| 1883 | string xlayerType = it_type->second; |
| 1884 | |
| 1885 | // Parse the input/output connections |
| 1886 | checkNumberOfTopAndBottom(src, -1, 1); |
| 1887 | |
| 1888 | // Check if atleast one bottom is present |
| 1889 | if(src.bottom_size() <= 0) |
| 1890 | { |
| 1891 | cerr << "[EP021] There should be atleast one bottom for concat layer: " << src.name() << endl; |
| 1892 | exit(-1); |
| 1893 | } |
| 1894 | |
| 1895 | // Create new XLayer |
| 1896 | XLayer* dst = new XLayer(src.name(), xlayerType, src.top(0)); |
| 1897 | |
| 1898 | // axis [OPTIONAL : default = 1] |
| 1899 | dst->concat_params->axis = src_parameter.has_axis() ? src_parameter.axis() : 1 ; |
| 1900 | |
| 1901 | // Extract Precision Parameters |
| 1902 | bool success = ExtractPrecisionParameters(src, *dst, false); |
| 1903 | if(!success) |
| 1904 | graph.precMissLayers.push_back(src.name()); |
| 1905 | |
| 1906 | // Finally add the XLayer to graph |
| 1907 | graph.layers[src.name()] = dst; |
| 1908 | |
| 1909 | // ----------------------------- Setup Blobs and Connections ----------------------- // |
| 1910 | |
| 1911 | // Concat has multiple bottom, so iterate through them |
| 1912 | |
| 1913 | for(int i = 0; i<src.bottom_size(); i++) |
| 1914 | { |
| 1915 | // Check bottom first. Make sure it is already registered in the Graph.blobs |
| 1916 | map<string, XBlob*>::iterator it = graph.checkIfBlobExists(src.bottom(i), true, false); |
| 1917 | |
| 1918 | // Execution here reached means, bottom blob exists in graph. So update its fields |
| 1919 | XBlob* tmpBottom = it->second; |
| 1920 | dst->bottom.push_back(nameIndex(tmpBottom)); // Add bottom to XLayer.bottom |
| 1921 | dst->bottomShape.push_back(tmpBottom->shape); // Replicate bottom shape in Layer also |
| 1922 | tmpBottom->consumers.push_back(dst->name); // Add convolution layer to bottom consumers |
| 1923 | tmpBottom->consumerDim.push_back(tmpBottom->shape); // and consumer uses the full bottom data. |
| 1924 | } |
| 1925 | |
| 1926 | // Check top. Make sure it is not registered in the Graph.blobs |
| 1927 | map<string, XBlob*>::iterator it = graph.checkIfBlobExists(src.top(0), true, true); |
| 1928 | |
| 1929 | // Execution reached here means, top blob doesn't exist, so create. |
| 1930 | XBlob* tmpTop = new XBlob(src.top(0)); |
| 1931 | dst->top.push_back(nameIndex(tmpTop)); // Add top blob to current layer top list |
| 1932 | |
| 1933 | // Update layer "top" info with top name and shape |
| 1934 | tmpTop->producers.push_back(dst->name); // Add current layer to top Producers list |
| 1935 | dst->computeOutputDim(); // Calculate the output blob shape |
no test coverage detected