Commit 08e7e108 authored by Cianciosa, Mark's avatar Cianciosa, Mark
Browse files

Fix row and column constant reductions. Do not combine if the dimensions are...

Fix row and column constant reductions. Do not combine if the dimensions are not the same. Add unit tests.
parent f786bb92
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -194,6 +194,7 @@ namespace graph {
                                    pr2->get_right());
            }

#if 1
//  Combine 2D and 1D piecewise constants if a row or column matches.
            if (pr2.get() && pr2->is_row_match(this->left)) {
                backend::buffer<T> result = pl1->evaluate();
@@ -224,6 +225,7 @@ namespace graph {
                                    pl2->get_left(),
                                    pl2->get_right());
            }
#endif

//  Idenity reductions.
            if (this->left->is_match(this->right)) {
@@ -708,6 +710,7 @@ namespace graph {
                                    pr2->get_right());
            }

#if 1
//  Combine 2D and 1D piecewise constants if a row or column matches.
            if (pr2.get() && pr2->is_row_match(this->left)) {
                backend::buffer<T> result = pl1->evaluate();
@@ -738,6 +741,7 @@ namespace graph {
                                    pl2->get_left(),
                                    pl2->get_right());
            }
#endif

//  Common factor reduction. If the left and right are both muliply nodes check
//  for a common factor. So you can change a*b - a*c -> a*(b - c).
@@ -1302,6 +1306,7 @@ namespace graph {
                                    pr2->get_right());
            }

#if 1
//  Combine 2D and 1D piecewise constants if a row or column matches.
            if (pr2.get() && pr2->is_row_match(this->left)) {
                backend::buffer<T> result = pl1->evaluate();
@@ -1332,6 +1337,7 @@ namespace graph {
                                    pl2->get_left(),
                                    pl2->get_right());
            }
#endif

//  Move constants to the left.
            if (is_constant_promotable(this->right, this->left)) {
@@ -2085,6 +2091,7 @@ namespace graph {
                                    pr2->get_right());
            }

#if 1
//  Combine 2D and 1D piecewise constants if a row or column matches.
            if (pr2.get() && pr2->is_row_match(this->left)) {
                backend::buffer<T> result = pl1->evaluate();
@@ -2115,6 +2122,7 @@ namespace graph {
                                    pl2->get_left(),
                                    pl2->get_right());
            }
#endif

            if (this->left->is_match(this->right)) {
                return one<T, SAFE_MATH> ();
+70 −70
Original line number Diff line number Diff line
@@ -308,9 +308,9 @@ namespace backend {

                const size_t num_colmns = size()/x.size();
                const size_t num_rows = x.size();
                for (size_t i = 0; i < num_colmns; i++) {
                    for (size_t j = 0; j < num_rows; j++) {
                        memory[i*num_rows + j] += x[j];
                for (size_t i = 0; i < num_rows; i++) {
                    for (size_t j = 0; j < num_colmns; j++) {
                        memory[i*num_rows + j] += x[i];
                    }
                }
            } else {
@@ -320,9 +320,9 @@ namespace backend {
                std::vector<T> m(x.size());
                const size_t num_colmns = x.size()/size();
                const size_t num_rows = size();
                for (size_t i = 0; i < num_colmns; i++) {
                    for (size_t j = 0; j < num_rows; j++) {
                        m[i*num_rows + j] = memory[j] + x[i*num_rows + j];
                for (size_t i = 0; i < num_rows; i++) {
                    for (size_t j = 0; j < num_colmns; j++) {
                        m[i*num_colmns + j] = memory[i] + x[i*num_colmns + j];
                    }
                }
                memory = m;
@@ -344,9 +344,9 @@ namespace backend {

                const size_t num_colmns = size()/x.size();
                const size_t num_rows = x.size();
                for (size_t i = 0; i < num_colmns; i++) {
                    for (size_t j = 0; j < num_rows; j++) {
                        memory[i*num_rows + j] += x[i];
                for (size_t i = 0; i < num_rows; i++) {
                    for (size_t j = 0; j < num_colmns; j++) {
                        memory[i*num_colmns + j] += x[j];
                    }
                }
            } else {
@@ -356,9 +356,9 @@ namespace backend {
                std::vector<T> m(x.size());
                const size_t num_colmns = x.size()/size();
                const size_t num_rows = size();
                for (size_t i = 0; i < num_colmns; i++) {
                    for (size_t j = 0; j < num_rows; j++) {
                        m[i*num_rows + j] = memory[i] + x[i*num_rows + j];
                for (size_t i = 0; i < num_rows; i++) {
                    for (size_t j = 0; j < num_colmns; j++) {
                        m[i*num_colmns + j] = memory[j] + x[i*num_colmns + j];
                    }
                }
                memory = m;
@@ -380,9 +380,9 @@ namespace backend {

                const size_t num_colmns = size()/x.size();
                const size_t num_rows = x.size();
                for (size_t i = 0; i < num_colmns; i++) {
                    for (size_t j = 0; j < num_rows; j++) {
                        memory[i*num_rows + j] -= x[j];
                for (size_t i = 0; i < num_rows; i++) {
                    for (size_t j = 0; j < num_colmns; j++) {
                        memory[i*num_colmns + j] -= x[i];
                    }
                }
            } else {
@@ -394,7 +394,7 @@ namespace backend {
                const size_t num_rows = size();
                for (size_t i = 0; i < num_colmns; i++) {
                    for (size_t j = 0; j < num_rows; j++) {
                        m[i*num_rows + j] = memory[j] - x[i*num_rows + j];
                        m[i*num_colmns + j] = memory[i] - x[i*num_colmns + j];
                    }
                }
                memory = m;
@@ -416,9 +416,9 @@ namespace backend {

                const size_t num_colmns = size()/x.size();
                const size_t num_rows = x.size();
                for (size_t i = 0; i < num_colmns; i++) {
                    for (size_t j = 0; j < num_rows; j++) {
                        memory[i*num_rows + j] -= x[i];
                for (size_t i = 0; i < num_rows; i++) {
                    for (size_t j = 0; j < num_colmns; j++) {
                        memory[i*num_colmns + j] -= x[j];
                    }
                }
            } else {
@@ -428,9 +428,9 @@ namespace backend {
                std::vector<T> m(x.size());
                const size_t num_colmns = x.size()/size();
                const size_t num_rows = size();
                for (size_t i = 0; i < num_colmns; i++) {
                    for (size_t j = 0; j < num_rows; j++) {
                        m[i*num_rows + j] = memory[i] - x[i*num_rows + j];
                for (size_t i = 0; i < num_rows; i++) {
                    for (size_t j = 0; j < num_colmns; j++) {
                        m[i*num_colmns + j] = memory[j] - x[i*num_colmns + j];
                    }
                }
                memory = m;
@@ -452,9 +452,9 @@ namespace backend {

                const size_t num_colmns = size()/x.size();
                const size_t num_rows = x.size();
                for (size_t i = 0; i < num_colmns; i++) {
                    for (size_t j = 0; j < num_rows; j++) {
                        memory[i*num_rows + j] *= x[j];
                for (size_t i = 0; i < num_rows; i++) {
                    for (size_t j = 0; j < num_colmns; j++) {
                        memory[i*num_colmns + j] *= x[i];
                    }
                }
            } else {
@@ -464,9 +464,9 @@ namespace backend {
                std::vector<T> m(x.size());
                const size_t num_colmns = x.size()/size();
                const size_t num_rows = size();
                for (size_t i = 0; i < num_colmns; i++) {
                    for (size_t j = 0; j < num_rows; j++) {
                        m[i*num_rows + j] = memory[j]*x[i*num_rows + j];
                for (size_t i = 0; i < num_rows; i++) {
                    for (size_t j = 0; j < num_colmns; j++) {
                        m[i*num_colmns + j] = memory[i]*x[i*num_colmns + j];
                    }
                }
                memory = m;
@@ -488,9 +488,9 @@ namespace backend {

                const size_t num_colmns = size()/x.size();
                const size_t num_rows = x.size();
                for (size_t i = 0; i < num_colmns; i++) {
                    for (size_t j = 0; j < num_rows; j++) {
                        memory[i*num_rows + j] *= x[i];
                for (size_t i = 0; i < num_rows; i++) {
                    for (size_t j = 0; j < num_colmns; j++) {
                        memory[i*num_colmns + j] *= x[j];
                    }
                }
            } else {
@@ -500,9 +500,9 @@ namespace backend {
                std::vector<T> m(x.size());
                const size_t num_colmns = x.size()/size();
                const size_t num_rows = size();
                for (size_t i = 0; i < num_colmns; i++) {
                    for (size_t j = 0; j < num_rows; j++) {
                        m[i*num_rows + j] = memory[i]*x[i*num_rows + j];
                for (size_t i = 0; i < num_rows; i++) {
                    for (size_t j = 0; j < num_colmns; j++) {
                        m[i*num_colmns + j] = memory[j]*x[i*num_colmns + j];
                    }
                }
                memory = m;
@@ -524,9 +524,9 @@ namespace backend {

                const size_t num_colmns = size()/x.size();
                const size_t num_rows = x.size();
                for (size_t i = 0; i < num_colmns; i++) {
                    for (size_t j = 0; j < num_rows; j++) {
                        memory[i*num_rows + j] /= x[j];
                for (size_t i = 0; i < num_rows; i++) {
                    for (size_t j = 0; j < num_colmns; j++) {
                        memory[i*num_colmns + j] /= x[i];
                    }
                }
            } else {
@@ -536,9 +536,9 @@ namespace backend {
                std::vector<T> m(x.size());
                const size_t num_colmns = x.size()/size();
                const size_t num_rows = size();
                for (size_t i = 0; i < num_colmns; i++) {
                    for (size_t j = 0; j < num_rows; j++) {
                        m[i*num_rows + j] = memory[j]/x[i*num_rows + j];
                for (size_t i = 0; i < num_rows; i++) {
                    for (size_t j = 0; j < num_colmns; j++) {
                        m[i*num_colmns + j] = memory[i]/x[i*num_colmns + j];
                    }
                }
                memory = m;
@@ -560,9 +560,9 @@ namespace backend {

                const size_t num_colmns = size()/x.size();
                const size_t num_rows = x.size();
                for (size_t i = 0; i < num_colmns; i++) {
                    for (size_t j = 0; j < num_rows; j++) {
                        memory[i*num_rows + j] /= x[i];
                for (size_t i = 0; i < num_rows; i++) {
                    for (size_t j = 0; j < num_colmns; j++) {
                        memory[i*num_colmns + j] /= x[j];
                    }
                }
            } else {
@@ -572,9 +572,9 @@ namespace backend {
                std::vector<T> m(x.size());
                const size_t num_colmns = x.size()/size();
                const size_t num_rows = size();
                for (size_t i = 0; i < num_colmns; i++) {
                    for (size_t j = 0; j < num_rows; j++) {
                        m[i*num_rows + j] = memory[i]/x[i*num_rows + j];
                for (size_t i = 0; i < num_rows; i++) {
                    for (size_t j = 0; j < num_colmns; j++) {
                        m[i*num_colmns + j] = memory[j]/x[i*num_colmns + j];
                    }
                }
                memory = m;
@@ -596,12 +596,12 @@ namespace backend {

                const size_t num_colmns = size()/x.size();
                const size_t num_rows = x.size();
                for (size_t i = 0; i < num_colmns; i++) {
                    for (size_t j = 0; j < num_rows; j++) {
                for (size_t i = 0; i < num_rows; i++) {
                    for (size_t j = 0; j < num_colmns; j++) {
                        if constexpr (jit::is_complex<T> ()) {
                            memory[i*num_rows + j] = std::atan(x[j]/memory[i*num_rows + j]);
                            memory[i*num_colmns + j] = std::atan(x[i]/memory[i*num_colmns + j]);
                        } else {
                            memory[i*num_rows + j] = std::atan2(x[j], memory[i*num_rows + j]);
                            memory[i*num_colmns + j] = std::atan2(x[i], memory[i*num_colmns + j]);
                        }
                    }
                }
@@ -612,12 +612,12 @@ namespace backend {
                std::vector<T> m(x.size());
                const size_t num_colmns = x.size()/size();
                const size_t num_rows = size();
                for (size_t i = 0; i < num_colmns; i++) {
                    for (size_t j = 0; j < num_rows; j++) {
                for (size_t i = 0; i < num_rows; i++) {
                    for (size_t j = 0; j < num_colmns; j++) {
                        if constexpr (jit::is_complex<T> ()) {
                            m[i*num_rows + j] = std::atan(x[i*num_rows + j]/memory[j]);
                            m[i*num_colmns + j] = std::atan(x[i*num_colmns + j]/memory[i]);
                        } else {
                            m[i*num_rows + j] = std::atan2(x[i*num_rows + j], memory[j]);
                            m[i*num_colmns + j] = std::atan2(x[i*num_colmns + j], memory[i]);
                        }
                    }
                }
@@ -643,9 +643,9 @@ namespace backend {
                for (size_t i = 0; i < num_colmns; i++) {
                    for (size_t j = 0; j < num_rows; j++) {
                        if constexpr (jit::is_complex<T> ()) {
                            memory[i*num_rows + j] = std::atan(x[i]/memory[i*num_rows + j]);
                            memory[i*num_colmns + j] = std::atan(x[j]/memory[i*num_colmns + j]);
                        } else {
                            memory[i*num_rows + j] = std::atan2(x[i], memory[i*num_rows + j]);
                            memory[i*num_colmns + j] = std::atan2(x[j], memory[i*num_colmns + j]);
                        }
                    }
                }
@@ -656,12 +656,12 @@ namespace backend {
                std::vector<T> m(x.size());
                const size_t num_colmns = x.size()/size();
                const size_t num_rows = size();
                for (size_t i = 0; i < num_colmns; i++) {
                    for (size_t j = 0; j < num_rows; j++) {
                for (size_t i = 0; i < num_rows; i++) {
                    for (size_t j = 0; j < num_colmns; j++) {
                        if constexpr (jit::is_complex<T> ()) {
                            m[i*num_rows + j] = std::atan(x[i*num_rows + j]/memory[i]);
                            m[i*num_colmns + j] = std::atan(x[i*num_colmns + j]/memory[j]);
                        } else {
                            m[i*num_rows + j] = std::atan2(x[i*num_rows + j], memory[i]);
                            m[i*num_colmns + j] = std::atan2(x[i*num_colmns + j], memory[j]);
                        }
                    }
                }
@@ -684,9 +684,9 @@ namespace backend {

                const size_t num_colmns = size()/x.size();
                const size_t num_rows = x.size();
                for (size_t i = 0; i < num_colmns; i++) {
                    for (size_t j = 0; j < num_rows; j++) {
                        memory[i*num_rows + j] = std::pow(memory[i*num_rows + j], x[j]);
                for (size_t i = 0; i < num_rows; i++) {
                    for (size_t j = 0; j < num_colmns; j++) {
                        memory[i*num_colmns + j] = std::pow(memory[i*num_colmns + j], x[i]);
                    }
                }
            } else {
@@ -698,7 +698,7 @@ namespace backend {
                const size_t num_rows = size();
                for (size_t i = 0; i < num_colmns; i++) {
                    for (size_t j = 0; j < num_rows; j++) {
                        m[i*num_rows + j] = std::pow(memory[j], x[i*num_rows + j]);
                        m[i*num_colmns + j] = std::pow(memory[i], x[i*num_colmns + j]);
                    }
                }
                memory = m;
@@ -720,9 +720,9 @@ namespace backend {

                const size_t num_colmns = size()/x.size();
                const size_t num_rows = x.size();
                for (size_t i = 0; i < num_colmns; i++) {
                    for (size_t j = 0; j < num_rows; j++) {
                        memory[i*num_rows + j] = std::pow(memory[i*num_rows + j], x[i]);
                for (size_t i = 0; i < num_rows; i++) {
                    for (size_t j = 0; j < num_colmns; j++) {
                        memory[i*num_colmns + j] = std::pow(memory[i*num_colmns + j], x[j]);
                    }
                }
            } else {
@@ -732,9 +732,9 @@ namespace backend {
                std::vector<T> m(x.size());
                const size_t num_colmns = x.size()/size();
                const size_t num_rows = size();
                for (size_t i = 0; i < num_colmns; i++) {
                    for (size_t j = 0; j < num_rows; j++) {
                        m[i*num_rows + j] = std::pow(memory[i], x[i*num_rows + j]);
                for (size_t i = 0; i < num_rows; i++) {
                    for (size_t j = 0; j < num_colmns; j++) {
                        m[i*num_colmns + j] = std::pow(memory[j], x[i*num_colmns + j]);
                    }
                }
                memory = m;
+2 −0
Original line number Diff line number Diff line
@@ -898,6 +898,7 @@ namespace graph {
                                    pr2->get_right());
            }

#if 1
//  Combine 2D and 1D piecewise constants if a row or column matches.
            if (pr2.get() && pr2->is_row_match(this->left)) {
                backend::buffer<T> result = pl1->evaluate();
@@ -928,6 +929,7 @@ namespace graph {
                                    pl2->get_left(),
                                    pl2->get_right());
            }
#endif

            auto lp = pow_cast(this->left);
//  Only run this reduction if the right is an integer constant value.
+4 −4
Original line number Diff line number Diff line
@@ -179,17 +179,17 @@ namespace gpu {
                    MTLTextureDescriptor *discriptor = [MTLTextureDescriptor new];
                    discriptor.textureType = MTLTextureType2D;
                    discriptor.pixelFormat = MTLPixelFormatR32Float;
                    discriptor.width = size[0];
                    discriptor.height = size[1];
                    discriptor.width = size[1];
                    discriptor.height = size[0];
                    discriptor.storageMode = MTLStorageModeManaged;
                    discriptor.cpuCacheMode = MTLCPUCacheModeWriteCombined;
                    discriptor.hazardTrackingMode = MTLHazardTrackingModeUntracked;
                    discriptor.usage = MTLTextureUsageShaderRead;
                    texture_arguments[data] = [device newTextureWithDescriptor:discriptor];
                    [texture_arguments[data] replaceRegion:MTLRegionMake2D(0, 0, size[0], size[1])
                    [texture_arguments[data] replaceRegion:MTLRegionMake2D(0, 0, size[1], size[0])
                                               mipmapLevel:0
                                                 withBytes:reinterpret_cast<float *> (data)
                                               bytesPerRow:4*size[0]];
                                               bytesPerRow:4*size[1]];

                    [encoder optimizeContentsForGPUAccess:texture_arguments[data]];
                }
+35 −7
Original line number Diff line number Diff line
@@ -439,7 +439,18 @@ void compile_index(std::ostringstream &stream,
//------------------------------------------------------------------------------
        bool is_arg_match(shared_leaf<T, SAFE_MATH> x) {
            auto temp = piecewise_1D_cast(x);
            return temp.get() && this->arg->is_match(temp->get_arg());
            return temp.get()                           &&
                   this->arg->is_match(temp->get_arg()) &&
                   (temp->get_size() == this->get_size());
        }

//------------------------------------------------------------------------------
///  @brief Get the size of the buffer.
///
///  @returns The size of the buffer.
//------------------------------------------------------------------------------
        size_t get_size() const {
            return leaf_node<T, SAFE_MATH>::backend_cache[data_hash].size();
        }
    };

@@ -620,6 +631,16 @@ void compile_index(std::ostringstream &stream,
            return num_columns;
        }

//------------------------------------------------------------------------------
///  @brief Get the number of columns.
///
///  @returns The number of columns in the constant.
//------------------------------------------------------------------------------
        size_t get_num_rows() const {
            return leaf_node<T, SAFE_MATH>::backend_cache[data_hash].size() /
                   num_columns;
        }

//------------------------------------------------------------------------------
///  @brief Evaluate the results of the piecewise constant.
///
@@ -968,7 +989,8 @@ void compile_index(std::ostringstream &stream,
            return temp.get()                                     &&
                   this->left->is_match(temp->get_left())         &&
                   this->right->is_match(temp->get_right())       &&
                   (num_columns == this->get_num_columns());
                   (temp->get_num_rows() == this->get_num_rows()) &&
                   (temp->get_num_columns() == this->get_num_columns());
        }

//------------------------------------------------------------------------------
@@ -979,18 +1001,24 @@ void compile_index(std::ostringstream &stream,
//------------------------------------------------------------------------------
        bool is_row_match(shared_leaf<T, SAFE_MATH> x) {
            auto temp = piecewise_1D_cast(x);
            return temp.get() && this->left->is_match(temp->get_arg());
            return temp.get()                            &&
                   this->left->is_match(temp->get_arg()) &&
                   (temp->get_size() == this->get_num_rows());
        }

//------------------------------------------------------------------------------
///  @brief Do the columns match.
///
///  The number of rows is the column dimension.
///
///  @params[in] x Node to match.
///  @returns True if the column arguments match.
//------------------------------------------------------------------------------
        bool is_col_match(shared_leaf<T, SAFE_MATH> x) {
            auto temp = piecewise_1D_cast(x);
            return temp.get() && this->right->is_match(temp->get_arg());
            return temp.get()                             &&
                   this->right->is_match(temp->get_arg()) &&
                   (temp->get_size() == this->get_num_columns());
        }
    };

Loading