Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial input for backend selection #2396

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
92 commits
Select commit Hold shift + click to select a range
bd08406
Initial input for backend selection
May 30, 2023
32f71af
Update dev/make/cmplr.gnu.mkl.mk
amgrigoriev Jun 2, 2023
4173888
Update dev/make/cmplr.gnu.ref.mk
amgrigoriev Jun 2, 2023
3b8d239
Merge branch 'master' into dev/agrigorev-backend-selection
Jun 2, 2023
ed7ce18
Merge branch 'dev/agrigorev-backend-selection' of https://github.com/…
Jun 2, 2023
aa55677
Changed default backend to 'mkl'
Jun 2, 2023
193bb58
Buildable onedal_c
Jun 6, 2023
cc3b2fd
Added clang support
Jun 6, 2023
18225a8
Update dev/make/cmplr.gnu.mkl.mk
amgrigoriev Jun 6, 2023
39049aa
Update dev/make/cmplr.gnu.ref.mk
amgrigoriev Jun 6, 2023
a531c0f
Compiler fixes for icc, icx, vc plus clang-format
Jun 6, 2023
137771c
Merge branch 'dev/agrigorev-backend-selection' of https://github.com/…
Jun 6, 2023
8f366b7
Update dev/make/cmplr.clang.ref.mk
amgrigoriev Jun 6, 2023
3ef7d08
adding support for selecting different math/rng/service backends in c…
Jun 22, 2023
34f6708
fixed build issue with kmeans serialization
Jun 22, 2023
1224a3f
Merge pull request #1 from makart19/dev/amk_bazel_backend_selection
amgrigoriev Jun 22, 2023
336e772
Merge branch 'master' into dev/agrigorev-backend-selection
napetrov Jun 27, 2023
d7b46ea
Introducing backend_config param selection to build.sh
napetrov Jun 27, 2023
f2ae2cf
Create openblas.sh
napetrov Jun 27, 2023
4c95148
Introduce CI build for BLAS backend
napetrov Jun 27, 2023
7463322
adding execute permission on openblas.sh
napetrov Jun 28, 2023
fd38304
Update cpp/daal/src/externals/config_ref.h
amgrigoriev Jul 10, 2023
2ed525f
Update cpp/daal/src/externals/config_ref.h
amgrigoriev Jul 10, 2023
1ccbe05
Addressed part of the comments
Jul 11, 2023
6f294aa
Clang-format
Jul 11, 2023
6fb3617
Turned off hyperthreadig for ref config in order to use TBB default n…
Jul 11, 2023
7049297
Addressed more comments
Jul 12, 2023
3565f22
Macro fixed (APPLE)
Jul 12, 2023
126a48b
More changes in REF RNG
Jul 13, 2023
3614c75
Update build.sh
napetrov Jul 13, 2023
0657a7e
Removed 'sed' from Makefile
Jul 13, 2023
2154d93
Merge branch 'master' into dev/agrigorev-backend-selection
Jul 13, 2023
8e7b69e
Merge branch 'dev/agrigorev-backend-selection' of https://github.com/…
Jul 13, 2023
1f53810
Update openblas.sh
napetrov Jul 13, 2023
6eae7d6
Removed config_template from BAZEL
Jul 13, 2023
2470da8
Merge branch 'dev/agrigorev-backend-selection' of https://github.com/…
Jul 13, 2023
22fcdb8
Removed backend_config_header from BAZEL
Jul 13, 2023
559c440
Update openblas.sh
napetrov Jul 13, 2023
438710b
Replaced safe function not supported by GNU
Jul 14, 2023
55d1d60
Merge branch 'dev/agrigorev-backend-selection' of https://github.com/…
Jul 14, 2023
62b8ece
Fixed bugs in ref backend for OpenBLAS build
Jul 14, 2023
c7b5906
Fixed bugs in ref backend for OpenBLAS build #2
Jul 14, 2023
d18b453
Reduced header file dependencies in REF backend; removed << operator …
Jul 14, 2023
a4b7f2f
Update ci.yml
napetrov Jul 14, 2023
518fc92
Fixed export on symbols for OpenBLAS build
Jul 15, 2023
29b8314
Merge branch 'dev/agrigorev-backend-selection' of https://github.com/…
Jul 15, 2023
5066010
export.def handling in bazel
Jul 15, 2023
409c945
Update cpp/daal/src/externals/service_math_ref.h
amgrigoriev Jul 29, 2023
41dd3c8
Added libfgortran to REF build
Jul 31, 2023
6b19917
Merge branch 'dev/agrigorev-backend-selection' of https://github.com/…
Jul 31, 2023
4b994fe
removed config_template auxiliary func
Aug 1, 2023
1149bf3
Merge pull request #2 from makart19/dev/upd_bazel_cfg_templ_appr
amgrigoriev Aug 1, 2023
94b5b88
Merge branch 'dev/agrigorev-backend-selection' of https://github.com/…
Aug 1, 2023
d94ae6a
Removed libgfortran for REF backend
Aug 1, 2023
dc06a4c
Merge branch 'master' into dev/agrigorev-backend-selection
Aug 1, 2023
240d4a0
Fixed BACKEND incdirs for oneAPI; addressed some comments
Aug 8, 2023
f539a75
Removed unnecessary includes; fixed ifdef in _DECLAR_ files
Aug 8, 2023
3e6fdeb
fixed omitted ifdef in _DECLAR_ files
Aug 8, 2023
6461eed
Clang-format
Aug 8, 2023
f45f762
Clang-format fix
Aug 9, 2023
44be116
Added an option to move compression to exclude list for examples
Aug 9, 2023
61b30fb
Excluded compression examples for all configurations
Aug 14, 2023
79bc570
revert some macros to __intel_compiler
Aug 15, 2023
a8395ab
replase some more macros
Aug 15, 2023
2f8fb63
add NO_FORTRAN=1 to openblas.sh script
Aug 15, 2023
49bd0eb
Merge pull request #3 from amgrigoriev/dev/pyakovlev-fix-macros
amgrigoriev Aug 15, 2023
e0d3dcc
Update cpp/daal/src/externals/service_service_ref.h
napetrov Aug 15, 2023
67d6a43
Fixed missed fpk symbols for oneapi examples (REF backend)
Aug 15, 2023
fb37075
Merge branch 'dev/agrigorev-backend-selection' of https://github.com/…
Aug 15, 2023
865e128
Update cpp/daal/src/externals/service_service_ref.h
amgrigoriev Aug 16, 2023
3dca371
Update cpp/daal/src/externals/service_service_ref.h
amgrigoriev Aug 16, 2023
693235f
Merge branch 'master' into dev/agrigorev-backend-selection
Aug 17, 2023
8d5ee02
Fixed error message in oneapi
Aug 17, 2023
be4e3f9
exclude failed examples with ref backend
Aug 17, 2023
5e5d405
Merge pull request #4 from amgrigoriev/dev/pyakovlev-add-exclude-exam…
amgrigoriev Aug 17, 2023
f73e50c
exclude examples for oneapi/cpp ifaces
Aug 18, 2023
2f9334a
Merge pull request #5 from amgrigoriev/dev/pyakovlev-exclude-oneapi-e…
amgrigoriev Aug 18, 2023
85e22d0
exclude mpi examples for ref backend
Aug 18, 2023
8c817a6
Merge pull request #6 from amgrigoriev/dev/pyakovlev-add-exclude-exam…
amgrigoriev Aug 18, 2023
1315182
Apply suggestions from code review
napetrov Aug 18, 2023
7ecf32c
AVX512_MIC cleanup
Aug 20, 2023
55de110
Merge branch 'master' into dev/agrigorev-backend-selection
Aug 20, 2023
9e6ee5a
Fixed CI pipeline
Aug 20, 2023
0c7c3e0
Added more includes for ONEAPI
Aug 20, 2023
a09c3ef
Update .ci/pipeline/ci.yml
napetrov Aug 21, 2023
243b094
Switch to core count for blas build
napetrov Aug 21, 2023
8fe15f0
Update .ci/env/openblas.sh
napetrov Aug 21, 2023
2858360
Adding _MKL suffix for job name
napetrov Aug 21, 2023
ee5458f
Fixing daal4py job dependency
napetrov Aug 21, 2023
7f127df
Merge branch 'master' into dev/agrigorev-backend-selection
Aug 24, 2023
d642dac
Merge branch 'master' into dev/agrigorev-backend-selection
Aug 25, 2023
31416b2
Attempt to fix warnings
Aug 25, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .bazelrc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ build -c opt \
--incompatible_require_linker_input_cc_api

# Aliases for user-defined flags
build --flag_alias=backend_config=@config//:backend_config
build --flag_alias=test_link_mode=@config//:test_link_mode
build --flag_alias=test_thread_mode=@config//:test_thread_mode
build --flag_alias=test_external_datasets=@config//:test_external_datasets
Expand Down
26 changes: 26 additions & 0 deletions .ci/env/openblas.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/bin/bash
#===============================================================================
# Copyright 2023 Intel Corporation
#
# 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.
#===============================================================================

sudo apt-get update
sudo apt-get install build-essential gcc gfortran
git clone https://github.com/xianyi/OpenBLAS.git
CoreCount=$(lscpu -p | grep -Ev '^#' | wc -l)
pushd OpenBLAS
make clean
napetrov marked this conversation as resolved.
Show resolved Hide resolved
make -j${CoreCount} NO_FORTRAN=1
make install PREFIX=../__deps/open_blas
popd
48 changes: 46 additions & 2 deletions .ci/pipeline/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:
displayName: 'clang-format check'
failOnStderr: true

- job: 'LinuxMakeGNU'
- job: 'LinuxMakeGNU_MKL'
timeoutInMinutes: 0
variables:
release.dir: '__release_lnx_gnu'
Expand Down Expand Up @@ -89,6 +89,50 @@ jobs:
condition: failed()
continueOnError: true

- job: 'LinuxMakeGNU_OpenBLAS'
napetrov marked this conversation as resolved.
Show resolved Hide resolved
timeoutInMinutes: 0
variables:
release.dir: '__release_lnx_gnu'
platform.type : 'lnx32e'
pool:
vmImage: 'ubuntu-22.04'
steps:
- script: |
sudo apt-get update && sudo apt-get install -y gcc-multilib g++-multilib dos2unix tree
conda create -n ci-env -q -y -c intel -c conda-forge impi-devel=2021.8.0 openjdk=17.0.3
displayName: 'apt-get and conda install'
- script: |
.ci/scripts/describe_system.sh
displayName: 'System info'
- script: |
.ci/scripts/build.sh --compiler gnu --optimizations avx2 --target daal --backend_config ref --conda-env ci-env
napetrov marked this conversation as resolved.
Show resolved Hide resolved
displayName: 'make daal'
- script: |
.ci/scripts/build.sh --compiler gnu --optimizations avx2 --target oneapi_c --backend_config ref
napetrov marked this conversation as resolved.
Show resolved Hide resolved
displayName: 'make oneapi_c'
- task: PublishPipelineArtifact@1
inputs:
artifactName: '$(platform.type) OpenBLAS build'
targetPath: '$(Build.Repository.LocalPath)/$(release.dir)'
displayName: 'Upload build artifacts'
continueOnError: true
- script: |
.ci/scripts/test.sh --test-kind examples --build-dir $(release.dir) --compiler gnu --interface daal/java --conda-env ci-env
displayName: 'daal/java examples'
- script: |
.ci/scripts/test.sh --test-kind examples --build-dir $(release.dir) --compiler gnu --interface daal/cpp --build_system cmake --backend ref
displayName: 'daal/cpp examples'
- script: |
.ci/scripts/test.sh --test-kind examples --build-dir $(release.dir) --compiler gnu --interface oneapi/cpp --build_system cmake --backend ref
displayName: 'oneapi/cpp examples'
- task: PublishPipelineArtifact@1
inputs:
artifactName: '$(platform.type) fail'
targetPath: '$(Build.Repository.LocalPath)/$(release.dir)'
displayName: 'Uploading on fail'
condition: failed()
continueOnError: true

- job: 'LinuxMakeDPCPP'
timeoutInMinutes: 0
variables:
Expand Down Expand Up @@ -259,7 +303,7 @@ jobs:
displayName: 'bazel-cache-limit'

- job: LinuxDaal4py
dependsOn: LinuxMakeGNU
dependsOn: LinuxMakeGNU_MKL
timeoutInMinutes: 0
variables:
release.dir: '__release_lnx_gnu'
Expand Down
21 changes: 18 additions & 3 deletions .ci/scripts/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ while [[ $# -gt 0 ]]; do
--target)
target="$2"
;;
--backend_config)
backend_config="$2"
;;
--conda-env)
conda_env="$2"
;;
Expand All @@ -45,6 +48,7 @@ OS=${PLATFORM::3}
ARCH=${PLATFORM:3:3}

optimizations=${optimizations:-avx2}
backend_config=${backend_config:-mkl}
GLOBAL_RETURN=0

if [ "${OS}" == "lnx" ]; then
Expand Down Expand Up @@ -83,16 +87,27 @@ else
fi

#main actions
echo "Call mkl and tbb scripts"
$(pwd)/dev/download_micromkl.sh with_gpu=${with_gpu}
echo "Call env scripts"
if [ "${backend_config}" == "mkl" ]; then
echo "Sourcing MKL env"
$(pwd)/dev/download_micromkl.sh with_gpu=${with_gpu}
elif [ "${backend_config}" == "ref" ]; then
echo "Sourcing ref(openblas) env"
if [ ! -d "__deps/open_blas" ]; then
$(pwd)/.ci/env/openblas.sh
fi
else
echo "Not supported backend env"
fi
$(pwd)/dev/download_tbb.sh
echo "Set Java PATH and CPATH from JAVA_HOME=${JAVA_HOME}"
export PATH=$JAVA_HOME/bin:$PATH
export CPATH=$JAVA_HOME/include:$JAVA_HOME/include/${java_os_name}:$CPATH
echo "Calling make"
make ${target:-daal_c} ${make_op} \
COMPILER=${compiler} \
REQCPU="${optimizations}"
REQCPU="${optimizations}" \
BACKEND_CONFIG="${backend_config}"
err=$?

if [ ${err} -ne 0 ]; then
Expand Down
11 changes: 10 additions & 1 deletion .ci/scripts/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ while [[ $# -gt 0 ]]; do
--build_system)
build_system="$2"
;;
--backend)
backend="$2"
;;
*)
echo "Unknown option: $1"
exit 1
Expand All @@ -53,6 +56,7 @@ OS=${PLATFORM::3}
ARCH=${PLATFORM:3:3}
full_arch=intel64
build_system=${build_system:-cmake}
backend=${backend:-mkl}

if [ "${OS}" == "lnx" ]; then
source /usr/share/miniconda/etc/profile.d/conda.sh
Expand Down Expand Up @@ -150,7 +154,12 @@ for link_mode in ${link_modes}; do
mkdir Build
fi

cmake -B Build -S . -G "Unix Makefiles" -DONEDAL_LINK=${link_mode} -DTBB_DIR=${TBBROOT}/lib/cmake/tbb
ref_backend="OFF"
if [ "${backend}" == "ref" ]; then
ref_backend="ON"
fi

cmake -B Build -S . -G "Unix Makefiles" -DONEDAL_LINK=${link_mode} -DTBB_DIR=${TBBROOT}/lib/cmake/tbb -DREF_BACKEND=${ref_backend}
err=$?
if [ ${err} -ne 0 ]; then
echo -e "$(date +'%H:%M:%S') CMAKE GENERATE FAILED\t\t"
Expand Down
6 changes: 6 additions & 0 deletions WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ micromkl_dpc_repo(
sha256 = "1bd9e3ef850d95d1ee00e0f04943c8ed2490175fca6a7b331cab91a124ab301e",
)

load("@onedal//dev/bazel/deps:openblas.bzl", "openblas_repo")
openblas_repo(
name = "openblas",
root_env_var = "OPENBLASROOT",
)

load("@onedal//dev/bazel/deps:tbb.bzl", "tbb_repo")
tbb_repo(
name = "tbb",
Expand Down
86 changes: 57 additions & 29 deletions cpp/daal/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,26 @@ load("@onedal//dev/bazel:daal.bzl",
daal_module(
name = "microvmlipp",
override_deps_lib_tag = True,
deps = [
"@micromkl//:vml_ipp",
# TODO: Currently vml_ipp lib depends on TBB, but it shouldn't
# Remove TBB from deps once problem with vml_ipp is resolved
"@tbb//:tbb_binary",
],
deps = select({
"@config//:backend_ref": [ ],
"//conditions:default": [
"@micromkl//:vml_ipp",
# TODO: Currently vml_ipp lib depends on TBB, but it shouldn't
# Remove TBB from deps once problem with vml_ipp is resolved
"@tbb//:tbb_binary",
],
}),
)

daal_module(
name = "micromkl_thread",
name = "mathbackend_thread",
override_deps_lib_tag = True,
deps = [
"@micromkl//:mkl_thr",
],
deps = select({
"@config//:backend_ref": [ "@openblas//:openblas",
],
"//conditions:default": [ "@micromkl//:mkl_thr",
],
}),
)

daal_patch_kernel_defines(
Expand All @@ -40,19 +46,24 @@ daal_module(

daal_module(
name = "includes",
hdrs = [
":kernel_defines",
hdrs = [ ":kernel_defines",
],
includes = [ "." ],
defines = [
"DAAL_NOTHROW_EXCEPTIONS",
"DAAL_HIDE_DEPRECATED",
],
deps = [
":public_includes",
"@micromkl//:headers",
"@micromkl_dpc//:headers",
],
deps = select({
"@config//:backend_ref": [
":public_includes",
"@openblas//:headers",
],
"//conditions:default": [
":public_includes",
"@micromkl//:headers",
"@micromkl_dpc//:headers",
],
}),
)

daal_generate_version(
Expand Down Expand Up @@ -111,11 +122,17 @@ daal_module(
name = "sycl",
hdrs = glob(["src/sycl/**/*.h", "src/sycl/**/*.cl"]),
srcs = glob(["src/sycl/**/*.cpp"]),
deps = [
":services",
"@onedal//cpp/daal/src/algorithms/engines:kernel",
"@micromkl_dpc//:headers",
],
deps = select({
"@config//:backend_ref": [
":services",
"@onedal//cpp/daal/src/algorithms/engines:kernel",
],
"//conditions:default": [
":services",
"@onedal//cpp/daal/src/algorithms/engines:kernel",
"@micromkl_dpc//:headers",
],
}),
)

daal_module(
Expand All @@ -128,12 +145,20 @@ daal_module(
"TBB_SUPPRESS_DEPRECATED_MESSAGES",
"TBB_USE_ASSERT=0",
],
deps = [
":threading_headers",
":micromkl_thread",
"@tbb//:tbb",
"@tbb//:tbbmalloc",
],
deps = select({
"@config//:backend_ref": [
":threading_headers",
":mathbackend_thread",
"@tbb//:tbb",
"@tbb//:tbbmalloc",
],
"//conditions:default": [
":threading_headers",
":mathbackend_thread",
"@tbb//:tbb",
"@tbb//:tbbmalloc",
],
Comment on lines +149 to +160
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the difference?

}),
)

daal_module(
Expand Down Expand Up @@ -242,7 +267,10 @@ daal_dynamic_lib(
deps = [
":threading_tbb",
],
def_file = "src/threading/export_lnx32e.def",
def_file = select({
"@config//:backend_ref": "src/threading/export_lnx32e.ref.def",
"//conditions:default": "src/threading/export_lnx32e.mkl.def",
}),
)

daal_module(
Expand Down
17 changes: 17 additions & 0 deletions cpp/daal/include/services/daal_defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -491,13 +491,30 @@ const int SERIALIZATION_DBSCAN_DISTRIBUTED_PARTIAL_RESULT_STEP13_ID = 121310;
} \
}

#define DAAL_OVERFLOW_CHECK_BY_MULTIPLICATION_THROW_IF_POSSIBLE(type, op1, op2) \
{ \
if (!(0 == (op1)) && !(0 == (op2))) \
{ \
volatile type r = (op1) * (op2); \
r /= (op1); \
if (!(r == (op2))) services::throwIfPossible(services::Status(services::ErrorBufferSizeIntegerOverflow)); \
} \
}

#define DAAL_OVERFLOW_CHECK_BY_ADDING(type, op1, op2) \
{ \
volatile type r = (op1) + (op2); \
r -= (op1); \
if (!(r == (op2))) return services::Status(services::ErrorBufferSizeIntegerOverflow); \
}

#define DAAL_OVERFLOW_CHECK_BY_ADDING_THROW_IF_POSSIBLE(type, op1, op2) \
{ \
volatile type r = (op1) + (op2); \
r -= (op1); \
if (!(r == (op2))) services::throwIfPossible(services::Status(services::ErrorBufferSizeIntegerOverflow)); \
}

#define DAAL_CHECK_STATUS_RETURN_IF_FAIL(statVal, returnObj) \
{ \
if (!(statVal)) return returnObj; \
Expand Down
2 changes: 1 addition & 1 deletion cpp/daal/src/algorithms/adaboost/adaboost_predict_impl.i
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ services::Status AdaBoostPredictKernel<method, algorithmFPType, cpu>::processBlo
}
}

Math<algorithmFPType, cpu>::vLog(nRowsInCurrentBlock * nClasses, p_block, pLog); // inplace
MathInst<algorithmFPType, cpu>::vLog(nRowsInCurrentBlock * nClasses, p_block, pLog); // inplace

service_memset<algorithmFPType, cpu>(pSumLog, 0.0, nRowsInCurrentBlock);

Expand Down
6 changes: 3 additions & 3 deletions cpp/daal/src/algorithms/adaboost/adaboost_train_impl.i
Original file line number Diff line number Diff line change
Expand Up @@ -181,14 +181,14 @@ services::Status AdaBoostTrainKernel<method, algorithmFPType, cpu>::adaboostSAMM
}

algorithmFPType cM =
learningRate * (Math<algorithmFPType, cpu>::sLog((one - errM) / errM) + Math<algorithmFPType, cpu>::sLog(nClasses - one));
learningRate * (MathInst<algorithmFPType, cpu>::sLog((one - errM) / errM) + MathInst<algorithmFPType, cpu>::sLog(nClasses - one));

/* Update weights */
for (size_t i = 0; i < nVectors; i++)
{
errFlag[i] *= cM;
}
Math<algorithmFPType, cpu>::vExp(nVectors, errFlag, errFlag);
MathInst<algorithmFPType, cpu>::vExp(nVectors, errFlag, errFlag);
algorithmFPType wSum = zero;
for (size_t i = 0; i < nVectors; i++)
{
Expand Down Expand Up @@ -337,7 +337,7 @@ services::Status AdaBoostTrainKernel<method, algorithmFPType, cpu>::adaboostSAMM
}
t[i] *= scaling;
}
Math<algorithmFPType, cpu>::vExp(nVectors, t, t);
MathInst<algorithmFPType, cpu>::vExp(nVectors, t, t);
for (size_t i = 0; i < nVectors; i++)
{
w[i] *= t[i];
Expand Down
Loading