<commit_before>/*
 *
 *  * Copyright 2015 Skymind,Inc.
 *  *
 *  *    Licensed under the Apache License, Version 2.0 (the "License");
 *  *    you may not use this file except in compliance with the License.
 *  *    You may obtain a copy of the License at
 *  *
 *  *        http://www.apache.org/licenses/LICENSE-2.0
 *  *
 *  *    Unless required by applicable law or agreed to in writing, software
 *  *    distributed under the License is distributed on an "AS IS" BASIS,
 *  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  *    See the License for the specific language governing permissions and
 *  *    limitations under the License.
 *
 *
 */

package org.nd4j.linalg.api.ops.executioner;


import org.nd4j.linalg.api.complex.IComplexNDArray;
import org.nd4j.linalg.api.complex.IComplexNumber;
import org.nd4j.linalg.api.complex.LinearViewComplexNDArray;
import org.nd4j.linalg.api.iter.NdIndexIterator;
import org.nd4j.linalg.api.ndarray.INDArray;
import org.nd4j.linalg.api.ndarray.LinearViewNDArray;
import org.nd4j.linalg.api.ops.Accumulation;
import org.nd4j.linalg.api.ops.Op;
import org.nd4j.linalg.api.ops.ScalarOp;
import org.nd4j.linalg.api.ops.TransformOp;
import org.nd4j.linalg.api.parallel.DefaultParallelExecutionProvider;
import org.nd4j.linalg.api.parallel.DefaultParallelExecutioner;
import org.nd4j.linalg.api.parallel.ParallelExecutionProvider;
import org.nd4j.linalg.api.parallel.ParallelExecutioner;
import org.nd4j.linalg.api.shape.Shape;
import org.nd4j.linalg.api.shape.loop.coordinatefunction.CoordinateFunction;
import org.nd4j.linalg.factory.Nd4j;
import org.nd4j.linalg.util.ArrayUtil;

import java.util.Arrays;

/**
 * Basic op executioner. Knows how to iterate over
 * the buffers of each respective ndarray and apply transformations
 *
 * @author <NAME>
 */
public class DefaultOpExecutioner implements OpExecutioner {

    protected ExecutionMode executionMode = ExecutionMode.JAVA;
    protected ParallelExecutionProvider parallelExecutionProvider;
    protected ParallelExecutioner executorService;

    public DefaultOpExecutioner() {
        String provider = System.getProperty(ParallelExecutionProvider.EXECUTOR_SERVICE_PROVIDER,DefaultParallelExecutionProvider.class.getName());
        try {
            Class<? extends ParallelExecutionProvider> executorServiceProvider = (Class<? extends ParallelExecutionProvider>) Class.forName(provider);
            this.parallelExecutionProvider = executorServiceProvider.newInstance();

        } catch (Exception e) {
            e.printStackTrace();
        }

        this.executorService = parallelExecutionProvider.getService();

    }

    @Override
    public ParallelExecutioner parallelExecutioner() {
        return executorService;
    }

    @Override
    public Op exec(Op op) {
        checkOp(op);

        if(op.isPassThrough()) {
            op.exec();
            return op;
        }
        if (op instanceof TransformOp) {
            final TransformOp t = (TransformOp) op;
            //make assumption x and z are same type
            if (!op.x().getClass().equals(t.z().getClass()) && !(op.x() instanceof LinearViewNDArray) && !(t.z() instanceof LinearViewNDArray))
                throw new IllegalArgumentException("Illegal operation. Origin and output ndarray must be same types. op.x was " + op.x().getClass().getName() + " while t.z was " + t.z().getClass().getName());
            if(op.y() != null &&  op.x().ordering() == op.y().ordering() && op.x().ordering() == op.z().ordering()) {
                for(int i = 0; i < op.n(); i++) {
                    op.z().putScalarUnsafe(i * op.z().elementWiseStride(), op.op(op.x().getDoubleUnsafe(i * op.x().elementWiseStride()), op.y().getDoubleUnsafe(op.y().elementWiseStride() * i)));
                }

            }

            else if(op.y() != null) {
                if(Arrays.equals(op.x().shape(),op.y().shape())) {
                    Shape.iterate(op.x(), new CoordinateFunction() {
                        @Override
                        public void process(int[]... coord) {
                            apply(t,coord[0],coord[0]);
                        }
                    });
                }
                else
                    Shape.iterate(op.x(), op.y(), new CoordinateFunction() {
                        @Override
                        public void process(int[]... coord) {
                            apply(t,coord[0],coord[1]);
                        }
                    });

            }

            else {
                NdIndexIterator iter = new NdIndexIterator(op.x().shape());
                for (int c = 0; c < op.n(); c++) {
                    apply(t, iter.next());
                }
            }

        }
        else if (op instanceof Accumulation) {
            Accumulation accumulation = (Accumulation) op;
            if(op.y() != null && Shape.opIsWholeBufferWithMatchingStrides(op)) {
                for(int i = 0; i < op.n(); i++) {
                    accumulation.update(op.op(op.x().data().getDouble(i), op.y().data().getDouble(i)));
                }

            }
       /*     else if(op.y() != null && Shape.opIsWithMatchingStrides(op)) {
                int xStride = op.x().ordering() == 'f' ? op.x().stride(-1) : op.x().stride(0);
                int yStride = op.y().ordering() == 'f' ? op.y().stride(-1) : op.y().stride(0);
                for(int i = 0; i < op.n(); i++) {
                    accumulation.update(op.op(op.x().getDouble(op.x().offset() + i * xStride), op.y().getDouble(op.y().offset() + i * yStride)));
                }
            }*/
            else if(Shape.opIsWholeBufferWithMatchingStrides(op)) {
                for(int i = 0; i < op.n(); i++) {
                    accumulation.update(op.op(op.x().data().getDouble(i)));
                }
            }


            else if(!(op.x() instanceof IComplexNDArray)) {
                if(op.y() != null) {
                    INDArray xLinear = op.x().reshape(1,op.x().length());
                    INDArray yLinear = op.y().reshape(1,op.y().length());
                    for(int i = 0; i < op.n(); i++) {
                        accumulation.update(op.op(xLinear.getDouble(0,i),yLinear.getDouble(0,i)));
                    }
                }
                else {
                    INDArray xLinear = op.x().reshape(1,op.x().length());
                    for(int i = 0; i < op.n(); i++) {
                        accumulation.update(op.op(xLinear.getDouble(0,i)));
                    }
                }

            }



            else {
                for (int c = 0; c < op.n(); c++) {
                    apply(accumulation, c);
                }
            }

        }

        else if (op instanceof ScalarOp) {
            ScalarOp scalarOp = (ScalarOp) op;
            if(op.isPassThrough())
                return scalarOp;
            INDArray zLinear = op.z();
            INDArray xLinear = op.x();
            if(xLinear.ordering() == zLinear.ordering()) {
                int length = xLinear.length();
                for(int i = 0; i < length; i++)  {
                    zLinear.putScalarUnsafe(i * zLinear.elementWiseStride(),scalarOp.op(xLinear.getDoubleUnsafe(i * xLinear.elementWiseStride())));
                }
            }

            else if (op.x() instanceof IComplexNDArray) {
                IComplexNDArray ndArray = (IComplexNDArray) op.z();
                for(int c = 0; c < op.n(); c++)
                    ndArray.putScalar(c, op.op(((IComplexNDArray) op.x()).getComplex(c)));
            }

        }


        return op;
    }

    @Override
    public INDArray execAndReturn(Op op) {
        if(op instanceof TransformOp) {<commit_msg>-1 fix on element wise stride<commit_after>/*
 *
 *  * Copyright 2015 Skymind,Inc.
 *  *
 *  *    Licensed under the Apache License, Version 2.0 (the "License");
 *  *    you may not use this file except in compliance with the License.
 *  *    You may obtain a copy of the License at
 *  *
 *  *        http://www.apache.org/licenses/LICENSE-2.0
 *  *
 *  *    Unless required by applicable law or agreed to in writing, software
 *  *    distributed under the License is distributed on an "AS IS" BASIS,
 *  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  *    See the License for the specific language governing permissions and
 *  *    limitations under the License.
 *
 *
 */

package org.nd4j.linalg.api.ops.executioner;


import org.nd4j.linalg.api.complex.IComplexNDArray;
import org.nd4j.linalg.api.complex.IComplexNumber;
import org.nd4j.linalg.api.complex.LinearViewComplexNDArray;
import org.nd4j.linalg.api.iter.NdIndexIterator;
import org.nd4j.linalg.api.ndarray.INDArray;
import org.nd4j.linalg.api.ndarray.LinearViewNDArray;
import org.nd4j.linalg.api.ops.Accumulation;
import org.nd4j.linalg.api.ops.Op;
import org.nd4j.linalg.api.ops.ScalarOp;
import org.nd4j.linalg.api.ops.TransformOp;
import org.nd4j.linalg.api.parallel.DefaultParallelExecutionProvider;
import org.nd4j.linalg.api.parallel.DefaultParallelExecutioner;
import org.nd4j.linalg.api.parallel.ParallelExecutionProvider;
import org.nd4j.linalg.api.parallel.ParallelExecutioner;
import org.nd4j.linalg.api.shape.Shape;
import org.nd4j.linalg.api.shape.loop.coordinatefunction.CoordinateFunction;
import org.nd4j.linalg.factory.Nd4j;
import org.nd4j.linalg.util.ArrayUtil;

import java.util.Arrays;

/**
 * Basic op executioner. Knows how to iterate over
 * the buffers of each respective ndarray and apply transformations
 *
 * @author <NAME>
 */
public class DefaultOpExecutioner implements OpExecutioner {

    protected ExecutionMode executionMode = ExecutionMode.JAVA;
    protected ParallelExecutionProvider parallelExecutionProvider;
    protected ParallelExecutioner executorService;

    public DefaultOpExecutioner() {
        String provider = System.getProperty(ParallelExecutionProvider.EXECUTOR_SERVICE_PROVIDER,DefaultParallelExecutionProvider.class.getName());
        try {
            Class<? extends ParallelExecutionProvider> executorServiceProvider = (Class<? extends ParallelExecutionProvider>) Class.forName(provider);
            this.parallelExecutionProvider = executorServiceProvider.newInstance();

        } catch (Exception e) {
            e.printStackTrace();
        }

        this.executorService = parallelExecutionProvider.getService();

    }

    @Override
    public ParallelExecutioner parallelExecutioner() {
        return executorService;
    }

    @Override
    public Op exec(Op op) {
        checkOp(op);

        if(op.isPassThrough()) {
            op.exec();
            return op;
        }
        if (op instanceof TransformOp) {
            final TransformOp t = (TransformOp) op;
            //make assumption x and z are same type
            if (!op.x().getClass().equals(t.z().getClass()))
                throw new IllegalArgumentException("Illegal operation. Origin and output ndarray must be same types. op.x was " + op.x().getClass().getName() + " while t.z was " + t.z().getClass().getName());
            if(op.y() != null &&  op.x().ordering() == op.y().ordering() && op.x().ordering() == op.z().ordering() && op.z().elementWiseStride() > 0 && op.y().elementWiseStride() > 0 && op.x().elementWiseStride() > 0) {
                for(int i = 0; i < op.n(); i++) {
                    op.z().putScalarUnsafe(i * op.z().elementWiseStride(), op.op(op.x().getDoubleUnsafe(i * op.x().elementWiseStride()), op.y().getDoubleUnsafe(op.y().elementWiseStride() * i)));
                }

            }

            else if(op.y() != null) {
                if(Arrays.equals(op.x().shape(),op.y().shape())) {
                    Shape.iterate(op.x(), new CoordinateFunction() {
                        @Override
                        public void process(int[]... coord) {
                            apply(t,coord[0],coord[0]);
                        }
                    });
                }
                else
                    Shape.iterate(op.x(), op.y(), new CoordinateFunction() {
                        @Override
                        public void process(int[]... coord) {
                            apply(t,coord[0],coord[1]);
                        }
                    });

            }

            else {
                NdIndexIterator iter = new NdIndexIterator(op.x().shape());
                for (int c = 0; c < op.n(); c++) {
                    apply(t, iter.next());
                }
            }

        }
        else if (op instanceof Accumulation) {
            Accumulation accumulation = (Accumulation) op;
            if(op.y() != null && Shape.opIsWholeBufferWithMatchingStrides(op)) {
                for(int i = 0; i < op.n(); i++) {
                    accumulation.update(op.op(op.x().data().getDouble(i), op.y().data().getDouble(i)));
                }

            }

            else if(Shape.opIsWholeBufferWithMatchingStrides(op)) {
                for(int i = 0; i < op.n(); i++) {
                    accumulation.update(op.op(op.x().data().getDouble(i)));
                }
            }


            else if(!(op.x() instanceof IComplexNDArray)) {
                if(op.y() != null) {
                    INDArray xLinear = op.x().reshape(1,op.x().length());
                    INDArray yLinear = op.y().reshape(1,op.y().length());
                    for(int i = 0; i < op.n(); i++) {
                        accumulation.update(op.op(xLinear.getDouble(0,i),yLinear.getDouble(0,i)));
                    }
                }
                else {
                    INDArray xLinear = op.x().reshape(1,op.x().length());
                    for(int i = 0; i < op.n(); i++) {
                        accumulation.update(op.op(xLinear.getDouble(0,i)));
                    }
                }

            }



            else {
                for (int c = 0; c < op.n(); c++) {
                    apply(accumulation, c);
                }
            }

        }

        else if (op instanceof ScalarOp) {
            ScalarOp scalarOp = (ScalarOp) op;
            if(op.isPassThrough())
                return scalarOp;
            INDArray zLinear = op.z();
            INDArray xLinear = op.x();
            if(xLinear.ordering() == zLinear.ordering() && xLinear.elementWiseStride() > 0 && zLinear.elementWiseStride() > 0) {
                int length = xLinear.length();
                for(int i = 0; i < length; i++)  {
                    zLinear.putScalarUnsafe(i * zLinear.elementWiseStride(),scalarOp.op(xLinear.getDoubleUnsafe(i * xLinear.elementWiseStride())));
                }
            }

            else if (op.x() instanceof IComplexNDArray) {
                IComplexNDArray ndArray = (IComplexNDArray) op.z();
                for(int c = 0; c < op.n(); c++)
                    ndArray.putScalar(c, op.op(((IComplexNDArray) op.x()).getComplex(c)));
            }

        }


        return op;
    }

    @Override
    public INDArray execAndReturn(Op op) {
        if(op instanceof TransformOp) {
{'fraction_non_alphanumeric': 0.1330551692165044, 'fraction_numerical': 0.006954102920723227, 'mean_word_length': 1.8943837454475752, 'pattern_counts': {'":': 0, '<': 28, '<?xml version=': 0, '>': 14, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5531526', 'n_tokens_mistral': 4578, 'n_tokens_neox': 4351, 'n_words': 883}